From f5437632f486b7d0a0a181c58f113c86d032b02c Mon Sep 17 00:00:00 2001 From: Christopher Speller Date: Mon, 24 Apr 2017 20:11:36 -0400 Subject: Upgrading server dependancies (#6215) --- .../nicksnyder/go-i18n/i18n/bundle/bundle.go | 101 ++++++++++++++++++--- 1 file changed, 86 insertions(+), 15 deletions(-) (limited to 'vendor/github.com/nicksnyder/go-i18n/i18n/bundle') diff --git a/vendor/github.com/nicksnyder/go-i18n/i18n/bundle/bundle.go b/vendor/github.com/nicksnyder/go-i18n/i18n/bundle/bundle.go index 155543bda..2ad1d7cc3 100644 --- a/vendor/github.com/nicksnyder/go-i18n/i18n/bundle/bundle.go +++ b/vendor/github.com/nicksnyder/go-i18n/i18n/bundle/bundle.go @@ -2,6 +2,7 @@ package bundle import ( + "bytes" "encoding/json" "fmt" "io/ioutil" @@ -11,6 +12,7 @@ import ( "github.com/nicksnyder/go-i18n/i18n/language" "github.com/nicksnyder/go-i18n/i18n/translation" + toml "github.com/pelletier/go-toml" "gopkg.in/yaml.v2" ) @@ -78,34 +80,103 @@ func (b *Bundle) ParseTranslationFileBytes(filename string, buf []byte) error { } func parseTranslations(filename string, buf []byte) ([]translation.Translation, error) { - var unmarshalFunc func([]byte, interface{}) error - switch format := filepath.Ext(filename); format { - case ".json": - unmarshalFunc = json.Unmarshal - case ".yaml": - unmarshalFunc = yaml.Unmarshal - default: - return nil, fmt.Errorf("unsupported file extension %s", format) + if len(buf) == 0 { + return []translation.Translation{}, nil } - var translationsData []map[string]interface{} - if len(buf) > 0 { - if err := unmarshalFunc(buf, &translationsData); err != nil { - return nil, fmt.Errorf("failed to load %s because %s", filename, err) + ext := filepath.Ext(filename) + + // `github.com/pelletier/go-toml` has an Unmarshal function, + // that can't unmarshal to maps, so we should parse TOML format separately. + if ext == ".toml" { + tree, err := toml.LoadReader(bytes.NewReader(buf)) + if err != nil { + return nil, err } + + m := make(map[string]map[string]interface{}) + for k, v := range tree.ToMap() { + m[k] = v.(map[string]interface{}) + } + + return parseFlatFormat(m) } - translations := make([]translation.Translation, 0, len(translationsData)) - for i, translationData := range translationsData { + // Then parse other formats. + if isStandardFormat(ext, buf) { + var standardFormat []map[string]interface{} + if err := unmarshal(ext, buf, &standardFormat); err != nil { + return nil, fmt.Errorf("failed to unmarshal %v: %v", filename, err) + } + return parseStandardFormat(standardFormat) + } else { + var flatFormat map[string]map[string]interface{} + if err := unmarshal(ext, buf, &flatFormat); err != nil { + return nil, fmt.Errorf("failed to unmarshal %v: %v", filename, err) + } + return parseFlatFormat(flatFormat) + } +} + +func isStandardFormat(ext string, buf []byte) bool { + firstRune := rune(buf[0]) + if (ext == ".json" && firstRune == '[') || (ext == ".yaml" && firstRune == '-') { + return true + } + return false +} + +// unmarshal finds an appropriate unmarshal function for ext +// (extension of filename) and unmarshals buf to out. out must be a pointer. +func unmarshal(ext string, buf []byte, out interface{}) error { + switch ext { + case ".json": + return json.Unmarshal(buf, out) + case ".yaml": + return yaml.Unmarshal(buf, out) + } + + return fmt.Errorf("unsupported file extension %v", ext) +} + +func parseStandardFormat(data []map[string]interface{}) ([]translation.Translation, error) { + translations := make([]translation.Translation, 0, len(data)) + for i, translationData := range data { t, err := translation.NewTranslation(translationData) if err != nil { - return nil, fmt.Errorf("unable to parse translation #%d in %s because %s\n%v", i, filename, err, translationData) + return nil, fmt.Errorf("unable to parse translation #%d because %s\n%v", i, err, translationData) } translations = append(translations, t) } return translations, nil } +// parseFlatFormat just converts data from flat format to standard format +// and passes it to parseStandardFormat. +// +// Flat format logic: +// key of data must be a string and data[key] must be always map[string]interface{}, +// but if there is only "other" key in it then it is non-plural, else plural. +func parseFlatFormat(data map[string]map[string]interface{}) ([]translation.Translation, error) { + var standardFormatData []map[string]interface{} + for id, translationData := range data { + dataObject := make(map[string]interface{}) + dataObject["id"] = id + if len(translationData) == 1 { // non-plural form + _, otherExists := translationData["other"] + if otherExists { + dataObject["translation"] = translationData["other"] + } + } else { // plural form + dataObject["translation"] = translationData + } + + standardFormatData = append(standardFormatData, dataObject) + } + + return parseStandardFormat(standardFormatData) +} + // AddTranslation adds translations for a language. // // It is useful if your translations are in a format not supported by LoadTranslationFile. -- cgit v1.2.3-1-g7c22