Files
ngzz-mc/internal/assets/lang.go

77 lines
2.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package assets
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
)
// Lang 语言表:指定语言覆盖层 + en_us 回退层(设计.md §2.4、UI与输入.md §5
type Lang struct {
keys map[string]string // 指定语言
fallback map[string]string // en_us 回退
}
// Get 取翻译;缺失回退 en_us再缺失返回键名本身便于发现缺失键
func (l *Lang) Get(key string) string {
if v, ok := l.keys[key]; ok {
return v
}
if v, ok := l.fallback[key]; ok {
return v
}
return key
}
// LoadLang 加载语言:先加载 en_us 作为回退层,再合并目标语言。
// 合并顺序:低优先级包 → 高优先级包(后者覆盖),与资源优先级链一致。
func (m *Manager) LoadLang(code string) (*Lang, error) {
fallback := make(map[string]string)
if code != "en_us" {
if err := m.loadLangInto("en_us", fallback); err != nil {
return nil, err
}
}
keys := make(map[string]string)
if err := m.loadLangInto(code, keys); err != nil {
return nil, err
}
return &Lang{keys: keys, fallback: fallback}, nil
}
// loadLangInto 按优先级从低到高合并所有包的 lang/<code>.json 到 dst。
func (m *Manager) loadLangInto(code string, dst map[string]string) error {
var paths []string
// 从低优先级到高优先级收集路径(逆序遍历包列表)
for i := len(m.packs) - 1; i >= 0; i-- {
p := m.packs[i]
for _, ns := range p.namespaces() {
path := filepath.Join(p.Root, "assets", ns, "lang", code+".json")
if fileExists(path) {
paths = append(paths, path)
}
}
}
if m.embeddedRoot != "" {
path := filepath.Join(m.embeddedRoot, "lang", code+".json")
if fileExists(path) {
paths = append(paths, path)
}
}
for _, path := range paths {
b, err := os.ReadFile(path)
if err != nil {
return fmt.Errorf("assets.loadLangInto %s: %w", code, err)
}
var kv map[string]string
if err := json.Unmarshal(b, &kv); err != nil {
return fmt.Errorf("assets.loadLangInto %s: %w", code, err)
}
for k, v := range kv {
dst[k] = v
}
}
return nil
}