Skip to content

Commit

Permalink
Fix for map[interface{}]interface{} to JSON conversion (#87)
Browse files Browse the repository at this point in the history
  • Loading branch information
geseq authored and hanzei committed Feb 11, 2019
1 parent d3a9fb1 commit c61a9df
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 0 deletions.
62 changes: 62 additions & 0 deletions conversions.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"net/url"
"strconv"
)
Expand Down Expand Up @@ -47,13 +48,74 @@ func SetURLValuesSliceKeySuffix(s string) error {
// JSON converts the contained object to a JSON string
// representation
func (m Map) JSON() (string, error) {
for k, v := range m {
m[k] = cleanUp(v)
}

result, err := json.Marshal(m)
if err != nil {
err = errors.New("objx: JSON encode failed with: " + err.Error())
}
return string(result), err
}

func cleanUpInterfaceArray(in []interface{}) []interface{} {
result := make([]interface{}, len(in))
for i, v := range in {
result[i] = cleanUp(v)
}
return result
}

func cleanUpInterfaceMap(in map[interface{}]interface{}) Map {
result := Map{}
for k, v := range in {
result[fmt.Sprintf("%v", k)] = cleanUp(v)
}
return result
}

func cleanUpStringMap(in map[string]interface{}) Map {
result := Map{}
for k, v := range in {
result[k] = cleanUp(v)
}
return result
}

func cleanUpMSIArray(in []map[string]interface{}) []Map {
result := make([]Map, len(in))
for i, v := range in {
result[i] = cleanUpStringMap(v)
}
return result
}

func cleanUpMapArray(in []Map) []Map {
result := make([]Map, len(in))
for i, v := range in {
result[i] = cleanUpStringMap(v)
}
return result
}

func cleanUp(v interface{}) interface{} {
switch v := v.(type) {
case []interface{}:
return cleanUpInterfaceArray(v)
case []map[string]interface{}:
return cleanUpMSIArray(v)
case map[interface{}]interface{}:
return cleanUpInterfaceMap(v)
case Map:
return cleanUpStringMap(v)
case []Map:
return cleanUpMapArray(v)
default:
return v
}
}

// MustJSON converts the contained object to a JSON string
// representation and panics if there is an error
func (m Map) MustJSON() string {
Expand Down
14 changes: 14 additions & 0 deletions conversions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,20 @@ func TestConversionJSON(t *testing.T) {
require.NoError(t, err)
assert.Equal(t, jsonString, result)
assert.Equal(t, jsonString, o.MustJSON())

i := objx.Map{
"a": map[interface{}]interface{}{"b": objx.Map{"c": map[interface{}]interface{}{"d": "e"}},
"f": []objx.Map{{"g": map[interface{}]interface{}{"h": "i"}}},
"j": []map[string]interface{}{{"k": map[interface{}]interface{}{"l": "m"}}},
"n": []interface{}{objx.Map{"o": "p"}},
},
}

jsonString = `{"a":{"b":{"c":{"d":"e"}},"f":[{"g":{"h":"i"}}],"j":[{"k":{"l":"m"}}],"n":[{"o":"p"}]}}`
result, err = i.JSON()
require.NoError(t, err)
assert.Equal(t, jsonString, result)
assert.Equal(t, jsonString, i.MustJSON())
}

func TestConversionJSONWithError(t *testing.T) {
Expand Down

0 comments on commit c61a9df

Please sign in to comment.