summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/nicksnyder/go-i18n/v2/internal/parse.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/nicksnyder/go-i18n/v2/internal/parse.go')
-rw-r--r--vendor/github.com/nicksnyder/go-i18n/v2/internal/parse.go112
1 files changed, 112 insertions, 0 deletions
diff --git a/vendor/github.com/nicksnyder/go-i18n/v2/internal/parse.go b/vendor/github.com/nicksnyder/go-i18n/v2/internal/parse.go
new file mode 100644
index 000000000..a5cee87c6
--- /dev/null
+++ b/vendor/github.com/nicksnyder/go-i18n/v2/internal/parse.go
@@ -0,0 +1,112 @@
+package internal
+
+import (
+ "encoding/json"
+ "fmt"
+ "os"
+
+ "golang.org/x/text/language"
+)
+
+// UnmarshalFunc unmarshals data into v.
+type UnmarshalFunc func(data []byte, v interface{}) error
+
+// MessageFile represents a parsed message file.
+type MessageFile struct {
+ Path string
+ Tag language.Tag
+ Format string
+ Messages []*Message
+}
+
+// ParseMessageFileBytes returns the messages parsed from file.
+func ParseMessageFileBytes(buf []byte, path string, unmarshalFuncs map[string]UnmarshalFunc) (*MessageFile, error) {
+ lang, format := parsePath(path)
+ tag := language.Make(lang)
+ messageFile := &MessageFile{
+ Path: path,
+ Tag: tag,
+ Format: format,
+ }
+ if len(buf) == 0 {
+ return messageFile, nil
+ }
+ unmarshalFunc := unmarshalFuncs[messageFile.Format]
+ if unmarshalFunc == nil {
+ if messageFile.Format == "json" {
+ unmarshalFunc = json.Unmarshal
+ } else {
+ return nil, fmt.Errorf("no unmarshaler registered for %s", messageFile.Format)
+ }
+ }
+ var raw interface{}
+ if err := unmarshalFunc(buf, &raw); err != nil {
+ return nil, err
+ }
+ switch data := raw.(type) {
+ case map[string]interface{}:
+ messageFile.Messages = make([]*Message, 0, len(data))
+ for id, data := range data {
+ m, err := NewMessage(data)
+ if err != nil {
+ return nil, err
+ }
+ m.ID = id
+ messageFile.Messages = append(messageFile.Messages, m)
+ }
+ case map[interface{}]interface{}:
+ messageFile.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)
+ }
+ m, err := NewMessage(data)
+ if err != nil {
+ return nil, err
+ }
+ m.ID = strid
+ messageFile.Messages = append(messageFile.Messages, m)
+ }
+ case []interface{}:
+ // Backward compatibility for v1 file format.
+ messageFile.Messages = make([]*Message, 0, len(data))
+ for _, data := range data {
+ m, err := NewMessage(data)
+ if err != nil {
+ return nil, err
+ }
+ messageFile.Messages = append(messageFile.Messages, m)
+ }
+ default:
+ return nil, fmt.Errorf("unsupported file format %T", raw)
+ }
+ return messageFile, nil
+}
+
+func parsePath(path string) (langTag, format string) {
+ formatStartIdx := -1
+ for i := len(path) - 1; i >= 0; i-- {
+ c := path[i]
+ if os.IsPathSeparator(c) {
+ if formatStartIdx != -1 {
+ langTag = path[i+1 : formatStartIdx]
+ }
+ return
+ }
+ if path[i] == '.' {
+ if formatStartIdx != -1 {
+ langTag = path[i+1 : formatStartIdx]
+ return
+ }
+ if formatStartIdx == -1 {
+ format = path[i+1:]
+ formatStartIdx = i
+ }
+ }
+ }
+ if formatStartIdx != -1 {
+ langTag = path[:formatStartIdx]
+ }
+ return
+}