diff --git a/README.md b/README.md index 5918fb7..cbce88a 100644 --- a/README.md +++ b/README.md @@ -235,6 +235,12 @@ Example: fmt.Println("verbose enabled") } +You can get deeply nested values by providing the expected key path. + +Example: + + viper.Get("log.verbose") // case-insensitive path .....etc + ### Marshaling You also have the option of Marshaling all or a specific value to a struct, map, etc. diff --git a/util.go b/util.go index 2f974d8..5aaa117 100644 --- a/util.go +++ b/util.go @@ -17,6 +17,7 @@ import ( "io" "os" "path/filepath" + "reflect" "runtime" "strings" "unicode" @@ -184,3 +185,23 @@ func parseSizeInBytes(sizeStr string) uint { return safeMul(uint(size), multiplier) } + +// Recursively walks through the source map, populating the index with keys representing +// the nesting of the value and the value itself. +func indexMap(source map[string]interface{}, prefix string, index map[string]interface{}) { + if len(prefix) > 0 { + prefix = prefix + INDEX_DELIM + } + + for key, val := range source { + + indexPath := strings.ToLower(prefix + key) + + v.index[indexPath] = val + + if reflect.TypeOf(val).Kind() == reflect.Map { + indexMap(cast.ToStringMap(val), indexPath, index) + } + } + +} diff --git a/viper.go b/viper.go index 3758af2..c3fe683 100644 --- a/viper.go +++ b/viper.go @@ -598,27 +598,13 @@ func (v *Viper) find(key string) interface{} { return nil } +// Recursively walks through the structure returned by +// AllSettings, indexing deeply nested values. +// It uses AllSettings in order to get a properly +// prioritized config structure. func (v *Viper) buildIndex() { v.index = make(map[string]interface{}) - v.indexMap(v.AllSettings(), "") -} - -func (v *Viper) indexMap(source map[string]interface{}, prefix string) { - if len(prefix) > 0 { - prefix = prefix + INDEX_DELIM - } - - for key, val := range source { - - indexPath := strings.ToLower(prefix + key) - - v.index[indexPath] = val - - if reflect.TypeOf(val).Kind() == reflect.Map { - v.indexMap(cast.ToStringMap(val), indexPath) - } - } - + indexMap(v.AllSettings(), "", v.index) } // Check to see if the key has been set in any of the data locations @@ -840,6 +826,8 @@ func (v *Viper) AllKeys() []string { return a } +// Return all keys found in the index, including the deeply +// nested keys. func AllIndexes() []string { return v.AllIndexes() } func (v *Viper) AllIndexes() []string { v.buildIndex()