Skip to content

Commit

Permalink
Convert floats to int when parsing JSON (#59)
Browse files Browse the repository at this point in the history
  • Loading branch information
hanzei authored Jan 29, 2018
1 parent 3f41636 commit ca93b98
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 3 deletions.
44 changes: 41 additions & 3 deletions map.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,50 @@ func MustFromJSON(jsonString string) Map {
//
// Returns an error if the JSON is invalid.
func FromJSON(jsonString string) (Map, error) {
var data Map
err := json.Unmarshal([]byte(jsonString), &data)
var m Map
err := json.Unmarshal([]byte(jsonString), &m)
if err != nil {
return Nil, err
}
return data, nil
m.tryConvertFloat64()
return m, nil
}

func (m Map) tryConvertFloat64() {
for k, v := range m {
switch v.(type) {
case float64:
f := v.(float64)
if float64(int(f)) == f {
m[k] = int(f)
}
case map[string]interface{}:
t := New(v)
t.tryConvertFloat64()
m[k] = t
case []interface{}:
m[k] = tryConvertFloat64InSlice(v.([]interface{}))
}
}
}

func tryConvertFloat64InSlice(s []interface{}) []interface{} {
for k, v := range s {
switch v.(type) {
case float64:
f := v.(float64)
if float64(int(f)) == f {
s[k] = int(f)
}
case map[string]interface{}:
t := New(v)
t.tryConvertFloat64()
s[k] = t
case []interface{}:
s[k] = tryConvertFloat64InSlice(v.([]interface{}))
}
}
return s
}

// FromBase64 creates a new Obj containing the data specified
Expand Down
24 changes: 24 additions & 0 deletions map_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,30 @@ func TestMapFromJSONWithError(t *testing.T) {
assert.Nil(t, m)
}

func TestConversionJSONInt(t *testing.T) {
jsonString :=
`{
"a": 1,
"b": {
"data": 1
},
"c": [1],
"d": [[1]]
}`
m, err := objx.FromJSON(jsonString)

assert.Nil(t, err)
require.NotNil(t, m)
assert.Equal(t, 1, m.Get("a").Int())
assert.Equal(t, 1, m.Get("b.data").Int())

assert.True(t, m.Get("c").IsInterSlice())
assert.Equal(t, 1, m.Get("c").InterSlice()[0])

assert.True(t, m.Get("d").IsInterSlice())
assert.Equal(t, []interface{}{1}, m.Get("d").InterSlice()[0])
}

func TestMapFromBase64String(t *testing.T) {
base64String := "eyJuYW1lIjoiTWF0In0="
o, err := objx.FromBase64(base64String)
Expand Down

0 comments on commit ca93b98

Please sign in to comment.