Flatten nested YAML data in specified config file
Signed-off-by: Ben Reedy <breed808@breed808.com>
This commit is contained in:
parent
96aa2cf095
commit
d7122930d0
|
@ -43,12 +43,14 @@ func NewResolver(file string) (*Resolver, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
var m map[string]string
|
||||
err = yaml.Unmarshal(b, &m)
|
||||
var rawValues map[string]interface{}
|
||||
err = yaml.Unmarshal(b, &rawValues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for k, v := range m {
|
||||
// Flatten nested YAML values
|
||||
flattenedValues := flatten(rawValues)
|
||||
for k, v := range flattenedValues {
|
||||
if _, ok := flags[k]; !ok {
|
||||
flags[k] = v
|
||||
}
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
package config
|
||||
|
||||
import "fmt"
|
||||
|
||||
// flatten flattens the nested struct.
|
||||
//
|
||||
// All keys will be joined by dot
|
||||
// e.g. {"a": {"b":"c"}} => {"a.b":"c"}
|
||||
// or {"a": {"b":[1,2]}} => {"a.b.0":1, "a.b.1": 2}
|
||||
func flatten(data map[string]interface{}) map[string]string {
|
||||
ret := make(map[string]string)
|
||||
for k, v := range data {
|
||||
switch typed := v.(type) {
|
||||
case map[interface{}]interface{}:
|
||||
for fk, fv := range flatten(convertMap(typed)) {
|
||||
ret[fmt.Sprintf("%s.%s", k, fk)] = fv
|
||||
}
|
||||
case map[string]interface{}:
|
||||
for fk, fv := range flatten(typed) {
|
||||
ret[fmt.Sprintf("%s.%s", k, fk)] = fv
|
||||
}
|
||||
case []interface{}:
|
||||
for fk, fv := range flattenSlice(typed) {
|
||||
ret[fmt.Sprintf("%s.%s", k, fk)] = fv
|
||||
}
|
||||
default:
|
||||
ret[k] = fmt.Sprint(typed)
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
func flattenSlice(data []interface{}) map[string]string {
|
||||
ret := make(map[string]string)
|
||||
for idx, v := range data {
|
||||
switch typed := v.(type) {
|
||||
case map[interface{}]interface{}:
|
||||
for fk, fv := range flatten(convertMap(typed)) {
|
||||
ret[fmt.Sprintf("%d,%s", idx, fk)] = fv
|
||||
}
|
||||
case map[string]interface{}:
|
||||
for fk, fv := range flatten(typed) {
|
||||
ret[fmt.Sprintf("%d,%s", idx, fk)] = fv
|
||||
}
|
||||
case []interface{}:
|
||||
for fk, fv := range flattenSlice(typed) {
|
||||
ret[fmt.Sprintf("%d,%s", idx, fk)] = fv
|
||||
}
|
||||
default:
|
||||
ret[fmt.Sprint(idx)] = fmt.Sprint(typed)
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func convertMap(originalMap map[interface{}]interface{}) map[string]interface{} {
|
||||
convertedMap := map[string]interface{}{}
|
||||
for key, value := range originalMap {
|
||||
convertedMap[key.(string)] = value
|
||||
}
|
||||
return convertedMap
|
||||
}
|
Loading…
Reference in New Issue