84 lines
2.5 KiB
Go
84 lines
2.5 KiB
Go
// Package translation defines the interface for a translation.
|
|
package translation
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/nicksnyder/go-i18n/i18n/language"
|
|
)
|
|
|
|
// Translation is the interface that represents a translated string.
|
|
type Translation interface {
|
|
// MarshalInterface returns the object that should be used
|
|
// to serialize the translation.
|
|
MarshalInterface() interface{}
|
|
ID() string
|
|
Template(language.Plural) *template
|
|
UntranslatedCopy() Translation
|
|
Normalize(language *language.Language) Translation
|
|
Backfill(src Translation) Translation
|
|
Merge(Translation) Translation
|
|
Incomplete(l *language.Language) bool
|
|
}
|
|
|
|
// SortableByID implements sort.Interface for a slice of translations.
|
|
type SortableByID []Translation
|
|
|
|
func (a SortableByID) Len() int { return len(a) }
|
|
func (a SortableByID) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
|
func (a SortableByID) Less(i, j int) bool { return a[i].ID() < a[j].ID() }
|
|
|
|
// NewTranslation reflects on data to create a new Translation.
|
|
//
|
|
// data["id"] must be a string and data["translation"] must be either a string
|
|
// for a non-plural translation or a map[string]interface{} for a plural translation.
|
|
func NewTranslation(data map[string]interface{}) (Translation, error) {
|
|
id, ok := data["id"].(string)
|
|
if !ok {
|
|
return nil, fmt.Errorf(`missing "id" key`)
|
|
}
|
|
var pluralObject map[string]interface{}
|
|
switch translation := data["translation"].(type) {
|
|
case string:
|
|
tmpl, err := newTemplate(translation)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &singleTranslation{id, tmpl}, nil
|
|
case map[interface{}]interface{}:
|
|
// The YAML parser uses interface{} keys so we first convert them to string keys.
|
|
pluralObject = make(map[string]interface{})
|
|
for k, v := range translation {
|
|
kStr, ok := k.(string)
|
|
if !ok {
|
|
return nil, fmt.Errorf(`invalid plural category type %T; expected string`, k)
|
|
}
|
|
pluralObject[kStr] = v
|
|
}
|
|
case map[string]interface{}:
|
|
pluralObject = translation
|
|
case nil:
|
|
return nil, fmt.Errorf(`missing "translation" key`)
|
|
default:
|
|
return nil, fmt.Errorf(`unsupported type for "translation" key %T`, translation)
|
|
}
|
|
|
|
templates := make(map[language.Plural]*template, len(pluralObject))
|
|
for k, v := range pluralObject {
|
|
pc, err := language.NewPlural(k)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
str, ok := v.(string)
|
|
if !ok {
|
|
return nil, fmt.Errorf(`plural category "%s" has value of type %T; expected string`, pc, v)
|
|
}
|
|
tmpl, err := newTemplate(str)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
templates[pc] = tmpl
|
|
}
|
|
return &pluralTranslation{id, templates}, nil
|
|
}
|