111 lines
2.2 KiB
Go
111 lines
2.2 KiB
Go
|
package config
|
||
|
|
||
|
import (
|
||
|
"os"
|
||
|
"reflect"
|
||
|
"regexp"
|
||
|
"strings"
|
||
|
|
||
|
"gopkg.in/yaml.v3"
|
||
|
)
|
||
|
|
||
|
type Cfg interface {
|
||
|
GetVar() []VarConfig
|
||
|
}
|
||
|
|
||
|
type VarConfig struct {
|
||
|
Name string `yaml:"name"`
|
||
|
Value string `yaml:"value"`
|
||
|
}
|
||
|
|
||
|
type ConfigLoader struct {
|
||
|
Var []VarConfig
|
||
|
Config interface{}
|
||
|
varDef *VarPattern
|
||
|
refstr []*reflect.Value
|
||
|
}
|
||
|
|
||
|
func LoadConfig(path string, out Cfg, varPattern *VarPattern) {
|
||
|
cl := &ConfigLoader{varDef: varPattern, refstr: []*reflect.Value{}}
|
||
|
data, err := os.ReadFile(path)
|
||
|
if err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
if err = yaml.Unmarshal(data, out); err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
cl.Var = out.GetVar()
|
||
|
cl.Config = out
|
||
|
cl.parse()
|
||
|
cl.refstr = []*reflect.Value{}
|
||
|
// cl.setConfigPtr(outi)
|
||
|
}
|
||
|
|
||
|
func (cl *ConfigLoader) findVarName(match string) string {
|
||
|
re := regexp.MustCompile(cl.varDef.getPatternCaptureName())
|
||
|
parts := re.FindStringSubmatch(match)
|
||
|
if len(parts) > 0 {
|
||
|
match = parts[1]
|
||
|
}
|
||
|
return match
|
||
|
}
|
||
|
|
||
|
func (cl *ConfigLoader) findVarValue(v string) string {
|
||
|
names := strings.SplitN(v, ".", 2)
|
||
|
if names[0] == "var" {
|
||
|
for _, varConfig := range cl.Var {
|
||
|
if varConfig.Name == names[1] {
|
||
|
v = varConfig.Value
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return v
|
||
|
}
|
||
|
|
||
|
func (cl *ConfigLoader) findStringRef(ref reflect.Value) {
|
||
|
switch ref.Kind() {
|
||
|
case reflect.Ptr, reflect.Interface:
|
||
|
cl.findStringRef(ref.Elem())
|
||
|
case reflect.Struct:
|
||
|
for i := 0; i < ref.NumField(); i++ {
|
||
|
refc := ref.Field(i)
|
||
|
cl.findStringRef(refc)
|
||
|
}
|
||
|
case reflect.Slice:
|
||
|
if !ref.IsNil() {
|
||
|
for i := 0; i < ref.Len(); i++ {
|
||
|
refc := ref.Index(i)
|
||
|
cl.findStringRef(refc)
|
||
|
}
|
||
|
}
|
||
|
case reflect.String:
|
||
|
if ref.Len() > 0 {
|
||
|
cl.refstr = append(cl.refstr, &ref)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (cl *ConfigLoader) parse() {
|
||
|
var name string
|
||
|
var tmp string
|
||
|
var parts []string
|
||
|
var re2 *regexp.Regexp
|
||
|
|
||
|
cl.findStringRef(reflect.ValueOf(&cl))
|
||
|
|
||
|
re := regexp.MustCompile(cl.varDef.getPatternVar())
|
||
|
for _, ref := range cl.refstr {
|
||
|
tmp = ref.String()
|
||
|
parts = re.FindStringSubmatch(tmp)
|
||
|
if len(parts) > 0 {
|
||
|
s := strings.SplitAfter(parts[1], cl.varDef.Close)
|
||
|
for _, part := range s {
|
||
|
name = cl.findVarName(part)
|
||
|
re2 = regexp.MustCompile(cl.varDef.getPatternVarName(name))
|
||
|
tmp = re2.ReplaceAllString(tmp, cl.findVarValue(name))
|
||
|
}
|
||
|
ref.SetString(tmp)
|
||
|
}
|
||
|
}
|
||
|
}
|