-
Notifications
You must be signed in to change notification settings - Fork 0
/
translator.go
93 lines (68 loc) · 2.01 KB
/
translator.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// Copyright 2022 Hyperscale. All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.
package translation
import (
"context"
"github.com/hyperscale-stack/locale"
"golang.org/x/text/language"
"golang.org/x/text/message"
"golang.org/x/text/message/catalog"
)
var _ Translator = (*translator)(nil)
type Translator interface {
GetSupportedLocale(tag language.Tag) language.Tag
Translate(ctx context.Context, key message.Reference, args ...interface{}) string
}
type translator struct {
catalog catalog.Catalog
defaultLocale language.Tag
supportedLocales []language.Tag
locales map[language.Tag]*message.Printer
matcher language.Matcher
}
func New(locales []language.Tag, opts ...Option) Translator {
t := &translator{
defaultLocale: defaultLocale,
supportedLocales: locales,
locales: make(map[language.Tag]*message.Printer, len(locales)+1),
}
for _, opt := range opts {
opt(t)
}
t.init()
return t
}
func (t *translator) init() {
supportedLocalesMap := map[language.Tag]struct{}{
t.defaultLocale: {},
}
supportedLocales := []language.Tag{
t.defaultLocale,
}
for _, tag := range t.supportedLocales {
if _, ok := supportedLocalesMap[tag]; !ok {
supportedLocalesMap[tag] = struct{}{}
supportedLocales = append(supportedLocales, tag)
}
}
t.supportedLocales = supportedLocales
opts := []message.Option{}
if t.catalog != nil {
opts = append(opts, message.Catalog(t.catalog))
}
for _, tag := range t.supportedLocales {
t.locales[tag] = message.NewPrinter(tag, opts...)
}
t.matcher = language.NewMatcher(supportedLocales)
}
func (t *translator) GetSupportedLocale(tag language.Tag) language.Tag {
tag, _, _ = t.matcher.Match(tag)
return tag
}
func (t *translator) Translate(ctx context.Context, key message.Reference, args ...interface{}) string {
tag := locale.FromContext(ctx)
tag = t.GetSupportedLocale(tag)
printer := t.locales[tag]
return printer.Sprintf(key, args...)
}