fix(i18n): broaden locale filename resolution
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
1ae029cfdb
commit
72b2e822d2
2 changed files with 50 additions and 5 deletions
28
loader.go
28
loader.go
|
|
@ -1,6 +1,7 @@
|
|||
package i18n
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io/fs"
|
||||
"path"
|
||||
"slices"
|
||||
|
|
@ -30,14 +31,21 @@ func (l *FSLoader) Load(lang string) (map[string]Message, *GrammarData, error) {
|
|||
variants := localeFilenameCandidates(lang)
|
||||
var data []byte
|
||||
var err error
|
||||
var firstNonMissingErr error
|
||||
for _, filename := range variants {
|
||||
filePath := path.Join(l.dir, filename)
|
||||
data, err = fs.ReadFile(l.fsys, filePath)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
if firstNonMissingErr == nil && !errors.Is(err, fs.ErrNotExist) {
|
||||
firstNonMissingErr = err
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
if firstNonMissingErr != nil {
|
||||
err = firstNonMissingErr
|
||||
}
|
||||
return nil, nil, log.E("FSLoader.Load", "locale not found: "+lang, err)
|
||||
}
|
||||
|
||||
|
|
@ -70,11 +78,21 @@ func localeFilenameCandidates(lang string) []string {
|
|||
}
|
||||
variants = append(variants, candidate)
|
||||
}
|
||||
addVariant(lang + ".json")
|
||||
addVariant(core.Replace(lang, "-", "_") + ".json")
|
||||
addVariant(core.Replace(lang, "_", "-") + ".json")
|
||||
if base := baseLanguageTag(lang); base != "" && base != lang {
|
||||
addVariant(base + ".json")
|
||||
canonical := normalizeLanguageTag(lang)
|
||||
addTag := func(tag string) {
|
||||
if tag == "" {
|
||||
return
|
||||
}
|
||||
addVariant(tag + ".json")
|
||||
addVariant(core.Replace(tag, "-", "_") + ".json")
|
||||
addVariant(core.Replace(tag, "_", "-") + ".json")
|
||||
}
|
||||
addTag(lang)
|
||||
if canonical != "" && canonical != lang {
|
||||
addTag(canonical)
|
||||
}
|
||||
if base := baseLanguageTag(canonical); base != "" && base != canonical {
|
||||
addTag(base)
|
||||
}
|
||||
return variants
|
||||
}
|
||||
|
|
|
|||
|
|
@ -187,6 +187,33 @@ func TestLocaleFilenameCandidates(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestLocaleFilenameCandidatesNormalisesCase(t *testing.T) {
|
||||
got := localeFilenameCandidates("en-us")
|
||||
want := []string{"en-us.json", "en_us.json", "en-US.json", "en_US.json", "en.json"}
|
||||
if !slices.Equal(got, want) {
|
||||
t.Fatalf("localeFilenameCandidates(en-us) = %v, want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFSLoaderLoadUsesCanonicalVariant(t *testing.T) {
|
||||
fs := fstest.MapFS{
|
||||
"locales/en-US.json": &fstest.MapFile{
|
||||
Data: []byte(`{
|
||||
"greeting": "hello"
|
||||
}`),
|
||||
},
|
||||
}
|
||||
|
||||
loader := NewFSLoader(fs, "locales")
|
||||
messages, _, err := loader.Load("en-us")
|
||||
if err != nil {
|
||||
t.Fatalf("Load(en-us) error: %v", err)
|
||||
}
|
||||
if got := messages["greeting"].Text; got != "hello" {
|
||||
t.Fatalf("Load(en-us) greeting = %q, want %q", got, "hello")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFlattenWithGrammar(t *testing.T) {
|
||||
messages := make(map[string]Message)
|
||||
grammar := &GrammarData{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue