config: fix lists (#2124)

This commit is contained in:
Jan-Otto Kröpke
2025-07-11 19:50:58 +02:00
committed by GitHub
parent b07e866b4a
commit eade0da514
3 changed files with 45 additions and 70 deletions

View File

@@ -19,72 +19,52 @@ package config
import (
"fmt"
"strconv"
"strings"
)
// 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[strconv.Itoa(idx)] = fmt.Sprint(typed)
}
}
return ret
}
func convertMap(originalMap map[interface{}]interface{}) map[string]interface{} {
convertedMap := map[string]interface{}{}
// convertMap converts a map with any comparable key type to a map with string keys.
func convertMap[K comparable, V any](originalMap map[K]V) map[string]V {
convertedMap := make(map[string]V, len(originalMap))
for key, value := range originalMap {
if keyString, ok := key.(string); ok {
if keyString, ok := any(key).(string); ok {
convertedMap[keyString] = value
}
}
return convertedMap
}
// flatten flattens a nested map, joining keys with dots.
// e.g. {"a": {"b":"c"}} => {"a.b":"c"}
func flatten(data map[string]any) map[string]string {
result := make(map[string]string)
flattenHelper("", data, result)
return result
}
func flattenHelper(prefix string, data map[string]any, result map[string]string) {
for k, v := range data {
fullKey := k
if prefix != "" {
fullKey = prefix + "." + k
}
switch val := v.(type) {
case map[any]any:
flattenHelper(fullKey, convertMap(val), result)
case map[string]any:
flattenHelper(fullKey, val, result)
case []any:
strSlice := make([]string, len(val))
for i, elem := range val {
strSlice[i] = fmt.Sprint(elem)
}
result[fullKey] = strings.Join(strSlice, ",")
default:
result[fullKey] = fmt.Sprint(val)
}
}
}