// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cloud . package langs import ( "errors" "fmt" "strings" "github.com/TeaOSLab/EdgeCommon/pkg/configutils" ) const varPrefix = "lang." type LangCode = string type Lang struct { code string messageMap map[MessageCode]string // message code => message text } func NewLang(code string) *Lang { return &Lang{ code: code, messageMap: map[MessageCode]string{}, } } func (this *Lang) Set(messageCode MessageCode, messageText string) { this.messageMap[messageCode] = messageText } func (this *Lang) Has(messageCode MessageCode) bool { _, ok := this.messageMap[messageCode] return ok } // Get 读取单条消息 // get single message with message code func (this *Lang) Get(messageCode MessageCode) string { return this.messageMap[messageCode] } // GetAll 读取所有消息 // get all messages func (this *Lang) GetAll() map[MessageCode]string { return this.messageMap } // Compile variable to literal strings func (this *Lang) Compile() error { for code, oldMessage := range this.messageMap { message, err := this.get(code, 0) if err != nil { return fmt.Errorf("compile '%s': '%s' failed: %w", string(code), oldMessage, err) } this.messageMap[code] = message } return nil } func (this *Lang) get(messageCode MessageCode, loopIndex int) (string, error) { if loopIndex >= 8 /** max recurse **/ { return "", errors.New("too many recurse") } loopIndex++ message, ok := this.messageMap[messageCode] if len(message) == 0 { if !ok && loopIndex > 1 { // recover as variable return "${" + varPrefix + string(messageCode) + "}", errors.New("can not find message for code '" + string(messageCode) + "'") } return "", nil } return configutils.ParseVariablesError(message, func(varName string) (value string, err error) { if !strings.HasPrefix(varName, varPrefix) { return "${" + varName + "}", nil } return this.get(MessageCode(varName[len(varPrefix):]), loopIndex) }) }