mirror of
https://github.com/spf13/viper
synced 2025-05-06 20:27:17 +00:00
Merge 68a8b52d7b
into 8dc2790b02
This commit is contained in:
commit
97befb3142
1 changed files with 56 additions and 1 deletions
57
viper.go
57
viper.go
|
@ -29,6 +29,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -512,6 +513,56 @@ func (v *Viper) searchMapWithPathPrefixes(source map[string]interface{}, path []
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v *Viper) searchMapWithArrayPrefix(source map[string]interface{}, path []string) interface{} {
|
||||||
|
if len(path) == 0 {
|
||||||
|
return source
|
||||||
|
}
|
||||||
|
|
||||||
|
next, ok := source[path[0]]
|
||||||
|
if ok {
|
||||||
|
// Immediate Key Value
|
||||||
|
if len(path) == 1 {
|
||||||
|
return next
|
||||||
|
}
|
||||||
|
|
||||||
|
// Value from Nested key
|
||||||
|
switch next.(type) {
|
||||||
|
case map[interface{}]interface{}:
|
||||||
|
return v.searchMapWithArrayPrefix(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.searchMapWithArrayPrefix(next.(map[string]interface{}), path[1:])
|
||||||
|
case []interface{}:
|
||||||
|
v1 := cast.ToSlice(next)
|
||||||
|
for k2, v2 := range v1 {
|
||||||
|
if reflect.TypeOf(v2).Kind() == reflect.Map {
|
||||||
|
if _, err := strconv.ParseInt(path[1], 10, 64); err == nil {
|
||||||
|
if strconv.Itoa(k2) == path[1] {
|
||||||
|
return v.searchMapWithArrayPrefix(cast.ToStringMap(v2), path[1:])
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return v.searchMapWithArrayPrefix(cast.ToStringMap(v2), path[1:])
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if _, err := strconv.ParseInt(path[1], 10, 64); err == nil {
|
||||||
|
if strconv.Itoa(k2) == path[1] {
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if _, err := strconv.ParseInt(path[0], 10, 64); err == nil {
|
||||||
|
return v.searchMapWithArrayPrefix(source, path[1:])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// isPathShadowedInDeepMap makes sure the given path is not shadowed somewhere
|
// isPathShadowedInDeepMap makes sure the given path is not shadowed somewhere
|
||||||
// on its path in the map.
|
// on its path in the map.
|
||||||
// e.g., if "foo.bar" has a value in the given map, it “shadows”
|
// e.g., if "foo.bar" has a value in the given map, it “shadows”
|
||||||
|
@ -882,7 +933,6 @@ func (v *Viper) BindEnv(input ...string) error {
|
||||||
// Viper will check to see if an alias exists first.
|
// Viper will check to see if an alias exists first.
|
||||||
// Note: this assumes a lower-cased key given.
|
// Note: this assumes a lower-cased key given.
|
||||||
func (v *Viper) find(lcaseKey string) interface{} {
|
func (v *Viper) find(lcaseKey string) interface{} {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
val interface{}
|
val interface{}
|
||||||
exists bool
|
exists bool
|
||||||
|
@ -956,6 +1006,11 @@ func (v *Viper) find(lcaseKey string) interface{} {
|
||||||
if val != nil {
|
if val != nil {
|
||||||
return val
|
return val
|
||||||
}
|
}
|
||||||
|
val = v.searchMapWithArrayPrefix(v.config, path)
|
||||||
|
if val != nil {
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
|
||||||
if nested && v.isPathShadowedInDeepMap(path, v.config) != "" {
|
if nested && v.isPathShadowedInDeepMap(path, v.config) != "" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue