package common import ( "encoding/json" "strconv" ) // JSONNumber is used instead of json.Number after upgrade to go 1.14 // to handle data which can be numbers in double quotes or possibly not numbers at all // see https://github.com/golang/go/issues/37308 type JSONNumber string // Float64 returns JSONNumber as float64 func (c JSONNumber) Float64() (float64, error) { f, err := strconv.ParseFloat(string(c), 64) if err != nil { return 0, err } return f, nil } // Int64 returns JSONNumber as int64 func (c JSONNumber) Int64() (int64, error) { i, err := strconv.ParseInt(string(c), 10, 64) if err != nil { return 0, err } return i, nil } func (c JSONNumber) String() string { return string(c) } // MarshalJSON marsalls JSONNumber to []byte // if possible, return a number without quotes, otherwise string value in quotes // empty string is treated as number 0 func (c JSONNumber) MarshalJSON() ([]byte, error) { if len(c) == 0 { return []byte("0"), nil } if f, err := c.Float64(); err == nil { return json.Marshal(f) } return json.Marshal(string(c)) } // UnmarshalJSON unmarshalls JSONNumber from []byte // if the value is in quotes, remove them func (c *JSONNumber) UnmarshalJSON(d []byte) error { s := string(d) l := len(s) if l > 1 && s[0] == '"' && s[l-1] == '"' { *c = JSONNumber(s[1 : l-1]) } else { *c = JSONNumber(s) } return nil }