package tmpls import ( "fmt" "github.com/kercylan98/minotaur/planner/pce" "strings" ) // NewGolang 创建一个 Golang 配置导出模板 func NewGolang(packageName string) *Golang { return &Golang{ Package: packageName, } } // Golang 配置导出模板 type Golang struct { Package string Templates []*pce.TmplStruct } func (slf *Golang) Render(templates ...*pce.TmplStruct) (string, error) { slf.Templates = templates return render(`// Code generated by minotaur. DO NOT EDIT. package {{.Package}} import ( jsonIter "github.com/json-iterator/go" "github.com/kercylan98/minotaur/utils/log" "sync" ) type Sign string const ( {{- range .Templates}} {{.Name}}Sign Sign = "{{.Name}}" {{- end}} ) var ( json = jsonIter.ConfigCompatibleWithStandardLibrary configs map[Sign]any signs = []Sign{ {{- range .Templates}} {{.Name}}Sign, {{- end}} } mutex sync.Mutex ) var ( {{- range .Templates}} {{- if $.HasIndex .}} {{.Name}} {{$.GetVariable .}} {{- end}} {{- end}} ) var ( {{- range .Templates}} {{- if $.HasIndex .}}{{- else}} {{.Name}} *{{$.GetConfigName .}} {{- end}} {{- end}} ) var ( {{- range .Templates}} {{- if $.HasIndex .}} _{{.Name}} {{$.GetVariable .}} {{- end}} {{- end}} ) var ( {{- range .Templates}} {{- if $.HasIndex .}}{{- else}} _{{.Name}} *{{$.GetConfigName .}} {{- end}} {{- end}} ) {{- range .Templates}} type {{$.GetConfigName .}} struct { {{- range .Fields}} {{- if .IsSlice}} {{- if .IsStruct}} {{.Name}} []*{{.Struct.Name}} // {{.Desc}} {{- else}} {{.Name}} []{{.Type}} // {{.Desc}} {{- end}} {{- else}} {{- if .IsStruct}} {{.Name}} *{{.Struct.Name}} // {{.Desc}} {{- else}} {{.Name}} {{.Type}} // {{.Desc}} {{- end}} {{- end}} {{- end}} } func (slf *{{$.GetConfigName .}}) String() string { if data, err := json.Marshal(slf); err == nil { return string(data) } return "{}" } {{- end}} {{- range .Templates}} {{- range .AllChildren}} type {{.Name}} struct { {{- range .Fields}} {{- if .IsSlice}} {{- if .IsStruct}} {{.Name}} []*{{.Struct.Name}} // {{.Desc}} {{- else}} {{.Name}} []{{.Type}} // {{.Desc}} {{- end}} {{- else}} {{- if .IsStruct}} {{.Name}} *{{.Struct.Name}} // {{.Desc}} {{- else}} {{.Name}} {{.Type}} // {{.Desc}} {{- end}} {{- end}} {{- end}} } {{- end}} {{- end}} // Load 通过自定义的方式加载配置 // - 通常建议使用该方法加载配置,因为仅执行一次加解锁 func LoadWithHandle(handle func(sign Sign, config any, json jsonIter.API) error) { mutex.Lock() defer mutex.Unlock() for _, sign := range signs { switch sign { {{- range .Templates}} case {{.Name}}Sign: {{- if $.HasIndex .}} temp := make({{$.GetVariable .}}) {{- else}} temp := new({{$.GetConfigName .}}) {{- end}} if err := handle(sign, &temp, json);err != nil { log.Error("Config", log.String("Name", "{{.Name}}"), log.Bool("Invalid", true), log.Err(err)) }else { _{{.Name}} = temp } {{- end}} } } } // LoadIndexConfig 通过 JSON 加载配置 func LoadWithJSON(sign Sign, data []byte) { switch sign { {{- range .Templates}} case {{.Name}}Sign: {{- if $.HasIndex .}} temp := make({{$.GetVariable .}}) {{- else}} temp := new({{$.GetConfigName .}}) {{- end}} if err := json.Unmarshal(data, &{{.Name}}); err != nil { log.Error("Config", log.String("Name", "{{.Name}}"), log.Bool("Invalid", true), log.Err(err)) return } _{{.Name}} = temp {{- end}} } } // Refresh 将加载后的配置刷新到线上 func Refresh() { mutex.Lock() defer mutex.Unlock() cs := make(map[Sign]any) {{- range .Templates}} {{.Name}} = _{{.Name}} cs[{{.Name}}Sign] = {{.Name}} {{- end}} configs = cs } // GetConfigs 获取所有配置 func GetConfigs() map[Sign]any { return configs } // GetConfigSigns 获取所有配置的标识 func GetConfigSigns() []Sign { return signs } `, slf) } func (slf *Golang) GetVariable(config *pce.TmplStruct) string { var prefix string for _, field := range config.Fields { if field.IsIndex() { prefix += fmt.Sprintf("map[%s]", field.Type) } } return fmt.Sprintf("%s*%s", prefix, slf.GetConfigName(config)) } func (slf *Golang) GetConfigName(config *pce.TmplStruct) string { return strings.ReplaceAll(config.Name, "Config", "Configuration") } func (slf *Golang) HasIndex(config *pce.TmplStruct) bool { return config.IndexCount > 0 }