2021-07-16 03:59:29 +03:00
|
|
|
package ini
|
|
|
|
|
|
|
|
import (
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/spf13/cast"
|
|
|
|
)
|
|
|
|
|
|
|
|
// THIS CODE IS COPIED HERE: IT SHOULD NOT BE MODIFIED
|
|
|
|
// AT SOME POINT IT WILL BE MOVED TO A COMMON PLACE
|
|
|
|
// deepSearch scans deep maps, following the key indexes listed in the
|
|
|
|
// sequence "path".
|
|
|
|
// The last value is expected to be another map, and is returned.
|
|
|
|
//
|
|
|
|
// In case intermediate keys do not exist, or map to a non-map value,
|
|
|
|
// a new map is created and inserted, and the search continues from there:
|
|
|
|
// the initial map "m" may be modified!
|
|
|
|
func deepSearch(m map[string]interface{}, path []string) map[string]interface{} {
|
|
|
|
for _, k := range path {
|
|
|
|
m2, ok := m[k]
|
|
|
|
if !ok {
|
|
|
|
// intermediate key does not exist
|
|
|
|
// => create it and continue from there
|
|
|
|
m3 := make(map[string]interface{})
|
|
|
|
m[k] = m3
|
|
|
|
m = m3
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
m3, ok := m2.(map[string]interface{})
|
|
|
|
if !ok {
|
|
|
|
// intermediate key is a value
|
|
|
|
// => replace with a new map
|
|
|
|
m3 = make(map[string]interface{})
|
|
|
|
m[k] = m3
|
|
|
|
}
|
|
|
|
// continue search from here
|
|
|
|
m = m3
|
|
|
|
}
|
|
|
|
return m
|
|
|
|
}
|
|
|
|
|
|
|
|
// flattenAndMergeMap recursively flattens the given map into a new map
|
2023-08-18 16:29:46 +03:00
|
|
|
// Code is based on the function with the same name in the main package.
|
2021-07-16 03:59:29 +03:00
|
|
|
// TODO: move it to a common place
|
|
|
|
func flattenAndMergeMap(shadow map[string]interface{}, m map[string]interface{}, prefix string, delimiter string) map[string]interface{} {
|
|
|
|
if shadow != nil && prefix != "" && shadow[prefix] != nil {
|
|
|
|
// prefix is shadowed => nothing more to flatten
|
|
|
|
return shadow
|
|
|
|
}
|
|
|
|
if shadow == nil {
|
|
|
|
shadow = make(map[string]interface{})
|
|
|
|
}
|
|
|
|
|
|
|
|
var m2 map[string]interface{}
|
|
|
|
if prefix != "" {
|
|
|
|
prefix += delimiter
|
|
|
|
}
|
|
|
|
for k, val := range m {
|
|
|
|
fullKey := prefix + k
|
2023-07-27 21:56:32 +03:00
|
|
|
switch val := val.(type) {
|
2021-07-16 03:59:29 +03:00
|
|
|
case map[string]interface{}:
|
2023-07-27 21:56:32 +03:00
|
|
|
m2 = val
|
2021-07-16 03:59:29 +03:00
|
|
|
case map[interface{}]interface{}:
|
|
|
|
m2 = cast.ToStringMap(val)
|
|
|
|
default:
|
|
|
|
// immediate value
|
|
|
|
shadow[strings.ToLower(fullKey)] = val
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
// recursively merge to shadow map
|
|
|
|
shadow = flattenAndMergeMap(shadow, m2, fullKey, delimiter)
|
|
|
|
}
|
|
|
|
return shadow
|
|
|
|
}
|