package grconfig import ( "bytes" "os" "path" "reflect" "strconv" "strings" ) type ConfigerChannelInterface interface { Item(item string, t interface{}) (err error) String(item string) string } type Configer struct { channels map[string]ConfigerChannelInterface root string } func New(root string) *Configer { return &Configer{root: root, channels: map[string]ConfigerChannelInterface{}} } func (conf *Configer) getData(item string) (ch ConfigerChannelInterface, err error) { var ok bool env := os.Getenv("CENTER_RUNMODE") chunks := strings.SplitN(item, ".", 2) if len(chunks) < 1 { panic("Item string error chunk len must more than 1") } if strings.TrimSpace(env) == "" { env = "" } if ch, ok = conf.channels[chunks[0]]; !ok { var fd *os.File var buf bytes.Buffer // @TODO 检查配置 fpath := path.Join(conf.root, env, chunks[0]+"."+"yaml") if fd, err = os.Open(fpath); err != nil { return nil, err } if _, err = buf.ReadFrom(fd); err != nil { return nil, err } // @TODO ch = &ConfigerChannelYAML{ tmp: parseYAML(buf), filename: chunks[0], } conf.channels[chunks[0]] = ch } return } func (conf *Configer) Item(item string, t interface{}) (err error) { ch, err1 := conf.getData(item) if err1 != nil { return err1 } return ch.Item(item, t) } func (conf *Configer) String(item string) string { ch, err1 := conf.getData(item) if err1 != nil { return "" } return ch.String(item) } func recursiveParse(item string, v interface{}) interface{} { if item == "" { return v } chunks := strings.SplitN(item, ".", 2) if n, err := strconv.Atoi(chunks[0]); err == nil { if tmp, ok := v.([]interface{}); reflect.TypeOf(v).Kind() == reflect.Slice && ok { v = tmp[n] } } else { if tmp, ok := v.(map[interface{}]interface{}); reflect.TypeOf(v).Kind() == reflect.Map && ok { v = tmp[chunks[0]] } } if len(chunks) <= 1 { return v } return recursiveParse(chunks[1], v) }