Skip to content

Commit c61a9df

Browse files
geseqhanzei
authored andcommitted
Fix for map[interface{}]interface{} to JSON conversion (#87)
1 parent d3a9fb1 commit c61a9df

File tree

2 files changed

+76
-0
lines changed

2 files changed

+76
-0
lines changed

conversions.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"encoding/base64"
66
"encoding/json"
77
"errors"
8+
"fmt"
89
"net/url"
910
"strconv"
1011
)
@@ -47,13 +48,74 @@ func SetURLValuesSliceKeySuffix(s string) error {
4748
// JSON converts the contained object to a JSON string
4849
// representation
4950
func (m Map) JSON() (string, error) {
51+
for k, v := range m {
52+
m[k] = cleanUp(v)
53+
}
54+
5055
result, err := json.Marshal(m)
5156
if err != nil {
5257
err = errors.New("objx: JSON encode failed with: " + err.Error())
5358
}
5459
return string(result), err
5560
}
5661

62+
func cleanUpInterfaceArray(in []interface{}) []interface{} {
63+
result := make([]interface{}, len(in))
64+
for i, v := range in {
65+
result[i] = cleanUp(v)
66+
}
67+
return result
68+
}
69+
70+
func cleanUpInterfaceMap(in map[interface{}]interface{}) Map {
71+
result := Map{}
72+
for k, v := range in {
73+
result[fmt.Sprintf("%v", k)] = cleanUp(v)
74+
}
75+
return result
76+
}
77+
78+
func cleanUpStringMap(in map[string]interface{}) Map {
79+
result := Map{}
80+
for k, v := range in {
81+
result[k] = cleanUp(v)
82+
}
83+
return result
84+
}
85+
86+
func cleanUpMSIArray(in []map[string]interface{}) []Map {
87+
result := make([]Map, len(in))
88+
for i, v := range in {
89+
result[i] = cleanUpStringMap(v)
90+
}
91+
return result
92+
}
93+
94+
func cleanUpMapArray(in []Map) []Map {
95+
result := make([]Map, len(in))
96+
for i, v := range in {
97+
result[i] = cleanUpStringMap(v)
98+
}
99+
return result
100+
}
101+
102+
func cleanUp(v interface{}) interface{} {
103+
switch v := v.(type) {
104+
case []interface{}:
105+
return cleanUpInterfaceArray(v)
106+
case []map[string]interface{}:
107+
return cleanUpMSIArray(v)
108+
case map[interface{}]interface{}:
109+
return cleanUpInterfaceMap(v)
110+
case Map:
111+
return cleanUpStringMap(v)
112+
case []Map:
113+
return cleanUpMapArray(v)
114+
default:
115+
return v
116+
}
117+
}
118+
57119
// MustJSON converts the contained object to a JSON string
58120
// representation and panics if there is an error
59121
func (m Map) MustJSON() string {

conversions_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,20 @@ func TestConversionJSON(t *testing.T) {
1818
require.NoError(t, err)
1919
assert.Equal(t, jsonString, result)
2020
assert.Equal(t, jsonString, o.MustJSON())
21+
22+
i := objx.Map{
23+
"a": map[interface{}]interface{}{"b": objx.Map{"c": map[interface{}]interface{}{"d": "e"}},
24+
"f": []objx.Map{{"g": map[interface{}]interface{}{"h": "i"}}},
25+
"j": []map[string]interface{}{{"k": map[interface{}]interface{}{"l": "m"}}},
26+
"n": []interface{}{objx.Map{"o": "p"}},
27+
},
28+
}
29+
30+
jsonString = `{"a":{"b":{"c":{"d":"e"}},"f":[{"g":{"h":"i"}}],"j":[{"k":{"l":"m"}}],"n":[{"o":"p"}]}}`
31+
result, err = i.JSON()
32+
require.NoError(t, err)
33+
assert.Equal(t, jsonString, result)
34+
assert.Equal(t, jsonString, i.MustJSON())
2135
}
2236

2337
func TestConversionJSONWithError(t *testing.T) {

0 commit comments

Comments
 (0)