mirror of
https://github.com/spf13/viper
synced 2024-12-22 11:37:02 +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
39
viper.go
39
viper.go
|
@ -107,6 +107,10 @@ func (rce RemoteConfigError) Error() string {
|
|||
// "endpoint": "https://localhost"
|
||||
// }
|
||||
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
|
||||
configPaths []string
|
||||
|
||||
|
@ -134,6 +138,7 @@ type Viper struct {
|
|||
// Returns an initialized Viper instance.
|
||||
func New() *Viper {
|
||||
v := new(Viper)
|
||||
v.keyDelim = "."
|
||||
v.configName = "config"
|
||||
v.config = make(map[string]interface{})
|
||||
v.override = make(map[string]interface{})
|
||||
|
@ -307,6 +312,26 @@ func (v *Viper) providerPathExists(p *remoteProvider) bool {
|
|||
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
|
||||
// Get can retrieve any value given the key to use
|
||||
// Get has the behavior of returning the value associated with the first
|
||||
|
@ -316,11 +341,19 @@ func (v *Viper) providerPathExists(p *remoteProvider) bool {
|
|||
// Get returns an interface. For a specific value use one of the Get____ methods.
|
||||
func Get(key string) interface{} { return v.Get(key) }
|
||||
func (v *Viper) Get(key string) interface{} {
|
||||
key = strings.ToLower(key)
|
||||
val := v.find(key)
|
||||
path := strings.Split(key, v.keyDelim)
|
||||
|
||||
val := v.find(strings.ToLower(key))
|
||||
|
||||
if val == nil {
|
||||
return 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) {
|
||||
|
|
Loading…
Reference in a new issue