stretchr / objx

Go package for dealing with maps, slices, JSON and other data.
MIT License
687 stars 75 forks source link

Automatically converting float to integer loses precision #99

Closed nphmuller closed 2 years ago

nphmuller commented 3 years ago

I'd expect the following test to succeed, but it doesn't. This is caused by the way float64 values are converted to integers in the current implementation. The tests demonstrates why json.Unmarshall probably chooses to unmarshall all numeric json values to float64 when unmarshalling to an interface.

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

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

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

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

A possible fix that could still support MustInt() etc. could be to do the conversion in the MustInt() methods. That way the expected float64 behaviour would persist, but integers could still be supported for ease of use.