mirror of
https://github.com/spf13/viper
synced 2024-12-22 19:47:01 +00:00
Added accessing deep keys by recursive hierarchical search
This commit is contained in:
parent
2578450e4a
commit
c174e2427c
1 changed files with 36 additions and 3 deletions
37
viper.go
37
viper.go
|
@ -107,6 +107,10 @@ func (rce RemoteConfigError) Error() string {
|
||||||
// "endpoint": "https://localhost"
|
// "endpoint": "https://localhost"
|
||||||
// }
|
// }
|
||||||
type Viper struct {
|
type Viper struct {
|
||||||
|
// Delimiter that separates a list of keys
|
||||||
|
// used to access a nested value in one go
|
||||||
|
keyDelim string
|
||||||
|
|
||||||
// A set of paths to look for the config file in
|
// A set of paths to look for the config file in
|
||||||
configPaths []string
|
configPaths []string
|
||||||
|
|
||||||
|
@ -134,6 +138,7 @@ type Viper struct {
|
||||||
// Returns an initialized Viper instance.
|
// Returns an initialized Viper instance.
|
||||||
func New() *Viper {
|
func New() *Viper {
|
||||||
v := new(Viper)
|
v := new(Viper)
|
||||||
|
v.keyDelim = "."
|
||||||
v.configName = "config"
|
v.configName = "config"
|
||||||
v.config = make(map[string]interface{})
|
v.config = make(map[string]interface{})
|
||||||
v.override = make(map[string]interface{})
|
v.override = make(map[string]interface{})
|
||||||
|
@ -307,6 +312,26 @@ func (v *Viper) providerPathExists(p *remoteProvider) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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[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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Viper is essentially repository for configurations
|
// Viper is essentially repository for configurations
|
||||||
// Get can retrieve any value given the key to use
|
// Get can retrieve any value given the key to use
|
||||||
// Get has the behavior of returning the value associated with the first
|
// Get has the behavior of returning the value associated with the first
|
||||||
|
@ -316,13 +341,21 @@ func (v *Viper) providerPathExists(p *remoteProvider) bool {
|
||||||
// Get returns an interface. For a specific value use one of the Get____ methods.
|
// Get returns an interface. For a specific value use one of the Get____ methods.
|
||||||
func Get(key string) interface{} { return v.Get(key) }
|
func Get(key string) interface{} { return v.Get(key) }
|
||||||
func (v *Viper) Get(key string) interface{} {
|
func (v *Viper) Get(key string) interface{} {
|
||||||
key = strings.ToLower(key)
|
path := strings.Split(key, v.keyDelim)
|
||||||
val := v.find(key)
|
|
||||||
|
val := v.find(strings.ToLower(key))
|
||||||
|
|
||||||
if val == nil {
|
if val == nil {
|
||||||
|
source := v.find(path[0])
|
||||||
|
if source == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if reflect.TypeOf(source).Kind() == reflect.Map {
|
||||||
|
val = v.searchMap(cast.ToStringMap(source), path[1:])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch val.(type) {
|
switch val.(type) {
|
||||||
case bool:
|
case bool:
|
||||||
return cast.ToBool(val)
|
return cast.ToBool(val)
|
||||||
|
|
Loading…
Reference in a new issue