func (v *Viper) Get(key string) interface{} { path := strings.Split(key, v.keyDelim) val := v.find(strings.ToLower(key)) if val == nil { source := v.find(path[0]) if source == nil { return nil } if reflect.TypeOf(source).Kind() == reflect.Map { val = v.searchMap(cast.ToStringMap(source), path[1:]) } } switch val.(type) { case bool: return cast.ToBool(val) case string: return cast.ToString(val) case int64, int32, int16, int8, int: return cast.ToInt(val) case float64, float32: return cast.ToFloat64(val) case time.Time: return cast.ToTime(val) case time.Duration: return cast.ToDuration(val) case []string: return val } return val }
func (v *Viper) searchMap(source map[string]interface{}, path []string) interface{} { if len(path) == 0 { return source } if next, ok := source[path[0]]; ok { switch next.(type) { case map[interface{}]interface{}: return v.searchMap(cast.ToStringMap(next), path[1:]) case map[string]interface{}: // Type assertion is safe here since it is only reached // if the type of `next` is the same as the type being asserted return v.searchMap(next.(map[string]interface{}), path[1:]) default: return next } } else { return nil } }
func (v *Viper) GetStringMap(key string) map[string]interface{} { return cast.ToStringMap(v.Get(key)) }