github.com/ShaleApps/viper@v1.15.1-concurrent/internal/encoding/javaproperties/map_utils.go (about) 1 package javaproperties 2 3 import ( 4 "strings" 5 6 "github.com/spf13/cast" 7 ) 8 9 // THIS CODE IS COPIED HERE: IT SHOULD NOT BE MODIFIED 10 // AT SOME POINT IT WILL BE MOVED TO A COMMON PLACE 11 // deepSearch scans deep maps, following the key indexes listed in the 12 // sequence "path". 13 // The last value is expected to be another map, and is returned. 14 // 15 // In case intermediate keys do not exist, or map to a non-map value, 16 // a new map is created and inserted, and the search continues from there: 17 // the initial map "m" may be modified! 18 func deepSearch(m map[string]interface{}, path []string) map[string]interface{} { 19 for _, k := range path { 20 m2, ok := m[k] 21 if !ok { 22 // intermediate key does not exist 23 // => create it and continue from there 24 m3 := make(map[string]interface{}) 25 m[k] = m3 26 m = m3 27 continue 28 } 29 m3, ok := m2.(map[string]interface{}) 30 if !ok { 31 // intermediate key is a value 32 // => replace with a new map 33 m3 = make(map[string]interface{}) 34 m[k] = m3 35 } 36 // continue search from here 37 m = m3 38 } 39 return m 40 } 41 42 // flattenAndMergeMap recursively flattens the given map into a new map 43 // Code is based on the function with the same name in tha main package. 44 // TODO: move it to a common place 45 func flattenAndMergeMap(shadow map[string]interface{}, m map[string]interface{}, prefix string, delimiter string) map[string]interface{} { 46 if shadow != nil && prefix != "" && shadow[prefix] != nil { 47 // prefix is shadowed => nothing more to flatten 48 return shadow 49 } 50 if shadow == nil { 51 shadow = make(map[string]interface{}) 52 } 53 54 var m2 map[string]interface{} 55 if prefix != "" { 56 prefix += delimiter 57 } 58 for k, val := range m { 59 fullKey := prefix + k 60 switch val.(type) { 61 case map[string]interface{}: 62 m2 = val.(map[string]interface{}) 63 case map[interface{}]interface{}: 64 m2 = cast.ToStringMap(val) 65 default: 66 // immediate value 67 shadow[strings.ToLower(fullKey)] = val 68 continue 69 } 70 // recursively merge to shadow map 71 shadow = flattenAndMergeMap(shadow, m2, fullKey, delimiter) 72 } 73 return shadow 74 }