Added accessing deep keys by recursive hierarchical search
diff --git a/viper.go b/viper.go
index e099839..a148209 100644
--- a/viper.go
+++ b/viper.go
@@ -107,6 +107,10 @@
// "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 @@
// 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 @@
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 @@
// 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) {