Initial Commit
This commit is contained in:
120
translate.go
Normal file
120
translate.go
Normal file
@@ -0,0 +1,120 @@
|
||||
package translate
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"hash/crc64"
|
||||
"io"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/pelletier/go-toml/v2"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
type Translations struct {
|
||||
Items []Translation `toml:"translation"`
|
||||
}
|
||||
|
||||
type Translation struct {
|
||||
ID uint64 `toml:"id"`
|
||||
Value string `toml:"value"`
|
||||
}
|
||||
|
||||
type Dictionary map[uint64]string
|
||||
type Catalog map[language.Tag]Dictionary
|
||||
|
||||
type Translator struct {
|
||||
cat Catalog
|
||||
Fallback language.Tag
|
||||
}
|
||||
|
||||
func New(cat Catalog) Translator {
|
||||
return Translator{cat, language.English}
|
||||
}
|
||||
|
||||
func NewFromDir(dir string) (Translator, error) {
|
||||
return NewFromFS(os.DirFS(dir))
|
||||
}
|
||||
|
||||
func NewFromFS(fsys fs.FS) (Translator, error) {
|
||||
cat := Catalog{}
|
||||
err := fs.WalkDir(fsys, ".", func(path string, d fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if d.IsDir() {
|
||||
return nil
|
||||
}
|
||||
|
||||
ext := filepath.Ext(path)
|
||||
if ext != ".toml" {
|
||||
return nil
|
||||
}
|
||||
|
||||
lang := filepath.Ext(strings.TrimSuffix(path, ext))
|
||||
lang = strings.TrimPrefix(lang, ".")
|
||||
|
||||
tag, err := language.Parse(lang)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fl, err := fsys.Open(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var tr Translations
|
||||
err = toml.NewDecoder(fl).Decode(&tr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fl.Close()
|
||||
|
||||
cat[tag] = toDict(tr)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return Translator{}, err
|
||||
}
|
||||
|
||||
fmt.Println(cat)
|
||||
|
||||
return Translator{cat, language.English}, nil
|
||||
}
|
||||
|
||||
func (t *Translator) TranslateTo(s string, tag language.Tag) string {
|
||||
dict, ok := t.cat[tag]
|
||||
if !ok {
|
||||
dict, ok = t.cat[t.Fallback]
|
||||
if !ok {
|
||||
return s
|
||||
}
|
||||
}
|
||||
id := hashString(s)
|
||||
str, ok := dict[id]
|
||||
if !ok {
|
||||
str = s
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
func toDict(tr Translations) Dictionary {
|
||||
out := Dictionary{}
|
||||
for _, item := range tr.Items {
|
||||
out[item.ID] = item.Value
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func hashString(s string) uint64 {
|
||||
hash := crc64.New(crc64.MakeTable(crc64.ISO))
|
||||
_, err := io.WriteString(hash, s)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return hash.Sum64()
|
||||
}
|
||||
Reference in New Issue
Block a user