diff --git a/provider/pkg/naming/convert.go b/provider/pkg/naming/convert.go index 48f762c7fa..39de03f1fa 100644 --- a/provider/pkg/naming/convert.go +++ b/provider/pkg/naming/convert.go @@ -288,13 +288,13 @@ func cfnValueToSdk(value interface{}) interface{} { } } -// ToStringifiedMap creates a copy of the input map with all primitive values converted to strings. -func ToStringifiedMap(value map[string]interface{}) map[string]interface{} { +// ToStringifiedMap creates a copy of the input map with all deeply nested primitive values converted to strings. +func ToStringifiedMap[K comparable](value map[K]interface{}) map[K]interface{} { if value == nil { return nil } - result := map[string]interface{}{} + result := map[K]interface{}{} for k, v := range value { result[k] = primitivesToString(v) } @@ -308,15 +308,13 @@ func primitivesToString(value interface{}) interface{} { switch reflect.TypeOf(value).Kind() { case reflect.Map: - valueMap, ok := value.(map[string]interface{}) - if !ok { - return value + mapValue := reflect.MakeMap(reflect.TypeOf(value)) + iter := reflect.ValueOf(value).MapRange() + for iter.Next() { + mapValue.SetMapIndex(iter.Key(), reflect.ValueOf(primitivesToString(iter.Value().Interface()))) } - result := map[string]interface{}{} - for k, v := range valueMap { - result[k] = primitivesToString(v) - } - return result + + return mapValue.Interface() case reflect.Slice, reflect.Array: s := reflect.ValueOf(value) result := make([]interface{}, s.Len()) diff --git a/provider/pkg/naming/convert_test.go b/provider/pkg/naming/convert_test.go index 768525ac98..3a3a1f4a75 100644 --- a/provider/pkg/naming/convert_test.go +++ b/provider/pkg/naming/convert_test.go @@ -385,8 +385,8 @@ func TestToStringifiedMap(t *testing.T) { expected: nil, }, { - name: "Empty map", - input: map[string]interface{}{}, + name: "Empty map", + input: map[string]interface{}{}, expected: map[string]interface{}{}, }, { @@ -442,15 +442,15 @@ func TestToStringifiedMap(t *testing.T) { }, "anotherKey": true, "arrayOfMaps": []interface{}{ - map[string]interface{}{ - "key1": "value1", - "key2": 2, - }, - map[string]interface{}{ - "key3": "value3", - "key4": 4, - }, + map[string]interface{}{ + "key1": "value1", + "key2": 2, }, + map[string]interface{}{ + "key3": "value3", + "key4": 4, + }, + }, }, }, expected: map[string]interface{}{ @@ -477,9 +477,45 @@ func TestToStringifiedMap(t *testing.T) { }, }, }, + { + name: "Map with arbitrary keys and deeply nested structures", + input: map[string]interface{}{ + "level1": map[interface{}]interface{}{ + 123: "numberKey", + true: map[string]interface{}{ + "nestedKey": []interface{}{ + map[string]interface{}{ + "key1": "value1", + "key2": 2, + }, + 3.14, + "string", + }, + }, + "anotherKey": false, + }, + }, + expected: map[string]interface{}{ + "level1": map[interface{}]interface{}{ + 123: "numberKey", + true: map[string]interface{}{ + "nestedKey": []interface{}{ + map[string]interface{}{ + "key1": "value1", + "key2": "2", + }, + "3.14", + "string", + }, + }, + "anotherKey": "false", + }, + }, + }, } for _, tt := range tests { + tt := tt t.Run(tt.name, func(t *testing.T) { t.Parallel() actual := ToStringifiedMap(tt.input) @@ -487,4 +523,3 @@ func TestToStringifiedMap(t *testing.T) { }) } } -