diff --git a/message/extract/extract.go b/message/extract/extract.go index 190ba79..ce38e69 100644 --- a/message/extract/extract.go +++ b/message/extract/extract.go @@ -41,7 +41,7 @@ type extractor struct { // Extract 提取本地化内容 // // o 给定的参数错误,可能会触发 panic,比如 o 为空、o.Funcs 格式错误等。 -func Extract(ctx context.Context, o *Options) (*message.Language, error) { +func Extract(ctx context.Context, o *Options) (*message.File, error) { if o == nil { panic("参数 o 不能为空") } @@ -62,7 +62,7 @@ func Extract(ctx context.Context, o *Options) (*message.Language, error) { slices.SortStableFunc(ex.msg, func(a, b message.Message) int { return cmp.Compare(a.Key, b.Key) }) - return &message.Language{ID: o.Language, Messages: ex.msg}, nil + return &message.File{ID: o.Language, Messages: ex.msg}, nil } func (ex *extractor) inspectDirs(ctx context.Context, dirs []string) error { diff --git a/message/message.go b/message/message.go index ac25120..fabc6ea 100644 --- a/message/message.go +++ b/message/message.go @@ -18,8 +18,8 @@ import ( ) type ( - // Language 某一语言的本地化内容 - Language struct { + // File 单个本地化语言组成的文件 + File struct { XMLName struct{} `xml:"language" json:"-" yaml:"-"` ID language.Tag `xml:"id,attr" json:"id" yaml:"id"` // 如果用字符串,还需要处理大小写以及不同值表示同一个 language.Tag 对象的问题 Messages []Message `xml:"message" json:"messages" yaml:"messages"` @@ -64,7 +64,7 @@ type ( // // -如果 l2 的 [Message.Key] 存在于 l,则覆盖 l 的项; // -如果 l2 的 [Message.Key] 不存在于 l,则写入 l; -func (l *Language) Join(l2 *Language) { +func (l *File) Join(l2 *File) { for index, m2 := range l2.Messages { elem, found := sliceutil.At(l.Messages, func(m1 Message, _ int) bool { return m1.Key == m2.Key }) if !found { @@ -84,16 +84,16 @@ func (l *Language) Join(l2 *Language) { // // 最终内容是 dest 为准。 // log 所有删除的记录都将通过此输出; -func (l *Language) MergeTo(log LogFunc, dest []*Language) { +func (f *File) MergeTo(log LogFunc, dest []*File) { for _, d := range dest { - l.mergeTo(log, d) + f.mergeTo(log, d) } } -func (l *Language) mergeTo(log LogFunc, dest *Language) { +func (f *File) mergeTo(log LogFunc, dest *File) { // 删除只存在于 dest 而不存在于 l 的内容 dest.Messages = sliceutil.Delete(dest.Messages, func(dm Message, _ int) bool { - exist := slices.IndexFunc(l.Messages, func(sm Message) bool { return sm.Key == dm.Key }) >= 0 + exist := slices.IndexFunc(f.Messages, func(sm Message) bool { return sm.Key == dm.Key }) >= 0 if !exist { log(localeutil.Phrase("the key %s of %s not found, will be deleted", strconv.Quote(dm.Key), dest.ID)) } @@ -101,7 +101,7 @@ func (l *Language) mergeTo(log LogFunc, dest *Language) { }) // 将 l 独有的项写入 dest - for _, sm := range l.Messages { + for _, sm := range f.Messages { if slices.IndexFunc(dest.Messages, func(dm Message) bool { return dm.Key == sm.Key }) < 0 { dest.Messages = append(dest.Messages, sm) } @@ -109,8 +109,8 @@ func (l *Language) mergeTo(log LogFunc, dest *Language) { } // Catalog 将本地化信息附加在 [catalog.Catalog] 上 -func (l *Language) Catalog(b *catalog.Builder) (err error) { - for _, msg := range l.Messages { +func (f *File) Catalog(b *catalog.Builder) (err error) { + for _, msg := range f.Messages { switch { case msg.Message.Vars != nil: vars := msg.Message.Vars @@ -120,12 +120,12 @@ func (l *Language) Catalog(b *catalog.Builder) (err error) { msgs = append(msgs, mm) } msgs = append(msgs, catalog.String(msg.Message.Msg)) - err = b.Set(l.ID, msg.Key, msgs...) + err = b.Set(f.ID, msg.Key, msgs...) case msg.Message.Select != nil: s := msg.Message.Select - err = b.Set(l.ID, msg.Key, plural.Selectf(s.Arg, s.Format, ex(s.Cases)...)) + err = b.Set(f.ID, msg.Key, plural.Selectf(s.Arg, s.Format, ex(s.Cases)...)) case msg.Message.Msg != "": - err = b.SetString(l.ID, msg.Key, msg.Message.Msg) + err = b.SetString(f.ID, msg.Key, msg.Message.Msg) } if err != nil { diff --git a/message/message_test.go b/message/message_test.go index cac8c70..dde8c55 100644 --- a/message/message_test.go +++ b/message/message_test.go @@ -18,11 +18,11 @@ import ( func TestLanguage_Join(t *testing.T) { a := assert.New(t, false) - src := &Language{ + src := &File{ ID: language.SimplifiedChinese, Messages: []Message{{Key: "src"}, {Key: "g", Message: Text{Msg: "src"}}}, } - l := &Language{ + l := &File{ ID: language.SimplifiedChinese, Messages: []Message{{Key: "l"}, {Key: "g", Message: Text{Msg: "l"}}}, } @@ -34,28 +34,28 @@ func TestLanguage_MergeTo(t *testing.T) { a := assert.New(t, false) log := func(s localeutil.Stringer) {} - dest := &Language{ + dest := &File{ ID: language.SimplifiedChinese, Messages: []Message{{Key: "dest"}}, } - l := &Language{ + l := &File{ ID: language.Afrikaans, Messages: []Message{{Key: "l"}}, } - l.MergeTo(log, []*Language{dest}) + l.MergeTo(log, []*File{dest}) a.Equal(dest.ID, language.SimplifiedChinese). Length(dest.Messages, 1).Equal(dest.Messages[0].Key, "l"). Length(l.Messages, 1).Equal(l.Messages[0].Key, "l") - dest = &Language{ + dest = &File{ ID: language.SimplifiedChinese, Messages: []Message{{Key: "dest"}, {Key: "g"}}, } - l = &Language{ + l = &File{ ID: language.SimplifiedChinese, Messages: []Message{{Key: "l"}, {Key: "g"}}, } - l.MergeTo(log, []*Language{dest}) + l.MergeTo(log, []*File{dest}) a.Length(dest.Messages, 2). Length(l.Messages, 2).Equal(l.Messages[0].Key, "l").Equal(l.Messages[1].Key, "g") } @@ -64,7 +64,7 @@ func TestLanguage_Catalog(t *testing.T) { a := assert.New(t, false) b := catalog.NewBuilder() - l := &Language{ + l := &File{ ID: language.SimplifiedChinese, Messages: []Message{ {Key: "k1", Message: Text{Msg: "msg1"}}, diff --git a/message/serialize/marshal.go b/message/serialize/marshal.go index 2f0509c..dee9c80 100644 --- a/message/serialize/marshal.go +++ b/message/serialize/marshal.go @@ -17,7 +17,7 @@ import ( type MarshalFunc = func(any) ([]byte, error) // Marshal 将 l 转换为 []byte -func Marshal(l *message.Language, f MarshalFunc) ([]byte, error) { +func Marshal(l *message.File, f MarshalFunc) ([]byte, error) { // 输出前排序,保证相同内容输出的内容是一样的。 slices.SortStableFunc(l.Messages, func(a, b message.Message) int { return cmp.Compare(a.Key, b.Key) }) return f(l) @@ -26,7 +26,7 @@ func Marshal(l *message.Language, f MarshalFunc) ([]byte, error) { // SaveFile 将 l 编码为文本并存入 path // // 如果文件已经存在会被覆盖。 -func SaveFile(l *message.Language, path string, f MarshalFunc, mode fs.FileMode) error { +func SaveFile(l *message.File, path string, f MarshalFunc, mode fs.FileMode) error { data, err := Marshal(l, f) if err == nil { err = os.WriteFile(path, data, mode) @@ -35,7 +35,7 @@ func SaveFile(l *message.Language, path string, f MarshalFunc, mode fs.FileMode) } // SaveFiles 将 langs 按语言 ID 分类保存 -func SaveFiles(langs []*message.Language, dir, ext string, f MarshalFunc, mode fs.FileMode) error { +func SaveFiles(langs []*message.File, dir, ext string, f MarshalFunc, mode fs.FileMode) error { if ext[0] != '.' { ext = "." + ext } diff --git a/message/serialize/unmarshal.go b/message/serialize/unmarshal.go index 8ec9bf7..d9323fe 100644 --- a/message/serialize/unmarshal.go +++ b/message/serialize/unmarshal.go @@ -19,23 +19,23 @@ type UnmarshalFunc = func([]byte, any) error type Search = func(string) UnmarshalFunc // Unmarshal 加载内容 -func Unmarshal(data []byte, u UnmarshalFunc) (*message.Language, error) { - l := &message.Language{} +func Unmarshal(data []byte, u UnmarshalFunc) (*message.File, error) { + l := &message.File{} if err := u(data, l); err != nil { return nil, err } return l, nil } -func LoadFile(path string, u UnmarshalFunc) (*message.Language, error) { +func LoadFile(path string, u UnmarshalFunc) (*message.File, error) { return unmarshalFS(func() ([]byte, error) { return os.ReadFile(path) }, u) } -func LoadFS(fsys fs.FS, name string, u UnmarshalFunc) (*message.Language, error) { +func LoadFS(fsys fs.FS, name string, u UnmarshalFunc) (*message.File, error) { return unmarshalFS(func() ([]byte, error) { return fs.ReadFile(fsys, name) }, u) } -func unmarshalFS(f func() ([]byte, error), u UnmarshalFunc) (*message.Language, error) { +func unmarshalFS(f func() ([]byte, error), u UnmarshalFunc) (*message.File, error) { data, err := f() if err != nil { return nil, err @@ -46,13 +46,13 @@ func unmarshalFS(f func() ([]byte, error), u UnmarshalFunc) (*message.Language, // LoadGlob 批量加载文件 // // 相同 Language.ID 的项会合并。 -func LoadGlob(s Search, glob string) ([]*message.Language, error) { +func LoadGlob(s Search, glob string) ([]*message.File, error) { matches, err := filepath.Glob(glob) if err != nil { return nil, err } - langs := make([]*message.Language, 0, len(matches)) + langs := make([]*message.File, 0, len(matches)) for _, match := range matches { u := s(match) if u == nil { @@ -71,8 +71,8 @@ func LoadGlob(s Search, glob string) ([]*message.Language, error) { // LoadFSGlob 批量加载文件 // // 相同 Language.ID 的项会合并。 -func LoadFSGlob(s Search, glob string, fsys ...fs.FS) ([]*message.Language, error) { - langs := make([]*message.Language, 0, 10) +func LoadFSGlob(s Search, glob string, fsys ...fs.FS) ([]*message.File, error) { + langs := make([]*message.File, 0, 10) for _, f := range fsys { matches, err := fs.Glob(f, glob) if err != nil { diff --git a/message/serialize/unmarshal_test.go b/message/serialize/unmarshal_test.go index 3dc6f34..ed647b1 100644 --- a/message/serialize/unmarshal_test.go +++ b/message/serialize/unmarshal_test.go @@ -39,5 +39,5 @@ func TestSaveFile(t *testing.T) { l2, err := LoadFS(os.DirFS("./testdata"), "cmn-hant.xml", xml.Unmarshal) a.NotError(err).NotNil(l2) - a.NotError(SaveFiles([]*message.Language{l1, l2}, "./testdata/", ".out", json.Marshal, os.ModePerm)) + a.NotError(SaveFiles([]*message.File{l1, l2}, "./testdata/", ".out", json.Marshal, os.ModePerm)) }