Skip to content

Commit

Permalink
Make ToStringifiedMap handle arbitrary map keys
Browse files Browse the repository at this point in the history
  • Loading branch information
flostadler committed Nov 8, 2024
1 parent 0f917e9 commit 4cd4ddb
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 22 deletions.
20 changes: 9 additions & 11 deletions provider/pkg/naming/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand All @@ -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())
Expand Down
57 changes: 46 additions & 11 deletions provider/pkg/naming/convert_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{}{},
},
{
Expand Down Expand Up @@ -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{}{
Expand All @@ -477,14 +477,49 @@ 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)
assert.Equal(t, tt.expected, actual)
})
}
}

0 comments on commit 4cd4ddb

Please sign in to comment.