Skip to content

Commit

Permalink
Fix go regression in json.Number unmarshalling (#312)
Browse files Browse the repository at this point in the history
  • Loading branch information
Slavek Kabrda authored Mar 11, 2020
1 parent f7dc02f commit 3c27c73
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 24 deletions.
37 changes: 13 additions & 24 deletions dashboards.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ type Yaxis struct {
func (y *Yaxis) UnmarshalJSON(data []byte) error {
type Alias Yaxis
wrapper := &struct {
Min *json.Number `json:"min,omitempty"`
Max *json.Number `json:"max,omitempty"`
Min *interface{} `json:"min,omitempty"`
Max *interface{} `json:"max,omitempty"`
*Alias
}{
Alias: (*Alias)(y),
Expand All @@ -125,31 +125,20 @@ func (y *Yaxis) UnmarshalJSON(data []byte) error {
return err
}

if wrapper.Min != nil {
if *wrapper.Min == "auto" {
y.AutoMin = true
y.Min = nil
} else {
f, err := wrapper.Min.Float64()
if err != nil {
return err
}
y.Min = &f
}
val, auto, err := GetFloatFromInterface(wrapper.Min)
if err != nil {
return fmt.Errorf(`faild parsing value for Yaxis.min: %s`, err.Error())
}
y.AutoMin = auto
y.Min = val

if wrapper.Max != nil {
if *wrapper.Max == "auto" {
y.AutoMax = true
y.Max = nil
} else {
f, err := wrapper.Max.Float64()
if err != nil {
return err
}
y.Max = &f
}
val, auto, err = GetFloatFromInterface(wrapper.Max)
if err != nil {
return fmt.Errorf(`faild parsing value for Yaxis.max: %s`, err.Error())
}
y.AutoMax = auto
y.Max = val

return nil
}

Expand Down
48 changes: 48 additions & 0 deletions helper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,51 @@ func TestHelperGetStringId(t *testing.T) {
assert.NotNil(t, err)
assert.Contains(t, err.Error(), "unsupported id type")
}

func TestGetFloatFromInterface(t *testing.T) {
var input interface{}

input = nil
val, auto, err := datadog.GetFloatFromInterface(nil)
assert.Nil(t, err)
assert.Equal(t, false, auto)
assert.Nil(t, val)

input = 0.0
val, auto, err = datadog.GetFloatFromInterface(&input)
assert.Nil(t, err)
assert.Equal(t, false, auto)
assert.Equal(t, 0.0, *val)

input = 12.3
val, auto, err = datadog.GetFloatFromInterface(&input)
assert.Nil(t, err)
assert.Equal(t, false, auto)
assert.Equal(t, 12.3, *val)

input = 123
val, auto, err = datadog.GetFloatFromInterface(&input)
assert.Nil(t, err)
assert.Equal(t, false, auto)
assert.Equal(t, 123.0, *val)

input = int64(1234567890123456789.0)
val, auto, err = datadog.GetFloatFromInterface(&input)
assert.Nil(t, err)
assert.Equal(t, false, auto)
assert.Equal(t, 1234567890123456789.0, *val)

input = "auto"
val, auto, err = datadog.GetFloatFromInterface(&input)
assert.Nil(t, err)
assert.Equal(t, true, auto)
assert.Nil(t, val)

input = "wrong!"
val, auto, err = datadog.GetFloatFromInterface(&input)
assert.NotNil(t, err)

input = false
val, auto, err = datadog.GetFloatFromInterface(&input)
assert.NotNil(t, err)
}
41 changes: 41 additions & 0 deletions helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ package datadog
import (
"encoding/json"
"errors"
"fmt"
"math"
"strconv"
)
Expand Down Expand Up @@ -122,3 +123,43 @@ func GetStringId(id interface{}) (string, error) {
return "", errors.New("unsupported id type")
}
}

func GetFloatFromInterface(intf *interface{}) (*float64, bool, error) {
var result *float64
var auto bool

if intf != nil {
val := *intf
switch tp := val.(type) {
case float32:
fv := float64(val.(float32))
result = &fv
case float64:
fv := val.(float64)
result = &fv
case int:
fv := float64(val.(int))
result = &fv
case int32:
fv := float64(val.(int32))
result = &fv
case int64:
fv := float64(val.(int64))
result = &fv
case string:
fv := val.(string)
if fv == "auto" {
auto = true
} else {
f, err := strconv.ParseFloat(fv, 64)
if err != nil {
return nil, false, err
}
result = &f
}
default:
return nil, false, fmt.Errorf(`bad type "%v" for Yaxis.min, expected "auto" or a number`, tp)
}
}
return result, auto, nil
}

0 comments on commit 3c27c73

Please sign in to comment.