nicksnyder / go-i18n

Translate your Go program into multiple languages.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

error `unsupported file format <nil>` when a yaml value is empty

LemonNekoGH opened this issue · comments

Here is minimum reproduction code, runs on version 1.22.1:
main.go

package main

import (
	"github.com/nicksnyder/go-i18n/v2/i18n"
	"golang.org/x/text/language"
	"gopkg.in/yaml.v3"
)

func main() {
	bundle := i18n.NewBundle(language.English)
	bundle.RegisterUnmarshalFunc("yaml", yaml.Unmarshal)
	_, err := bundle.LoadMessageFile("en.yaml")
	if err != nil {
		panic(err)
	}

	localizer := i18n.NewLocalizer(bundle, language.English.String())
	localizedStr := localizer.MustLocalize(&i18n.LocalizeConfig{
		MessageID: "empty-key",
	})

	println(localizedStr)
}

en.yaml

key: value
empty-key-but-type-specified: ''
empty-key:

The yaml.Unmarshal function will return nil value when a key with empty value, and nil won't be matched in the code:

go-i18n/i18n/parse.go

Lines 63 to 117 in 521f196

switch data := raw.(type) {
case string:
if isInitialCall {
return nil, errInvalidTranslationFile
}
m, err := NewMessage(data)
return []*Message{m}, err
case map[string]interface{}:
if isMapMessage {
m, err := NewMessage(data)
return []*Message{m}, err
}
messages = make([]*Message, 0, len(data))
for id, data := range data {
// recursively scan map items
messages, err = addChildMessages(id, data, messages)
if err != nil {
return nil, err
}
}
case map[interface{}]interface{}:
if isMapMessage {
m, err := NewMessage(data)
return []*Message{m}, err
}
messages = make([]*Message, 0, len(data))
for id, data := range data {
strid, ok := id.(string)
if !ok {
return nil, fmt.Errorf("expected key to be string but got %#v", id)
}
// recursively scan map items
messages, err = addChildMessages(strid, data, messages)
if err != nil {
return nil, err
}
}
case []interface{}:
// Backward compatibility for v1 file format.
messages = make([]*Message, 0, len(data))
for _, data := range data {
// recursively scan slice items
childMessages, err := recGetMessages(data, isMessage(data), false)
if err != nil {
return nil, err
}
messages = append(messages, childMessages...)
}
default:
return nil, fmt.Errorf("unsupported file format %T", raw)
}

Should we fallback to empty string "" when we got nil value?

Yeah that probably makes sense. I would accept a PR that adds a test and fixes this.