Skip to content

Commit

Permalink
Fix scientific notation decoding and add encoding test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
morris-kelly committed Jul 11, 2024
1 parent b2a8cc6 commit 84014b3
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 1 deletion.
15 changes: 15 additions & 0 deletions decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,21 @@ func (d *Decoder) fileToNode(f *ast.File) ast.Node {
func (d *Decoder) convertValue(v reflect.Value, typ reflect.Type, src ast.Node) (reflect.Value, error) {
if typ.Kind() != reflect.String {
if !v.Type().ConvertibleTo(typ) {

// Special case for "strings -> floats" aka scientific notation
// If the destination type is a float and the source type is a string, check if we can
// use strconv.ParseFloat to convert the string to a float.
if (typ.Kind() == reflect.Float32 || typ.Kind() == reflect.Float64) &&
v.Type().Kind() == reflect.String {
if f, err := strconv.ParseFloat(v.String(), 64); err == nil {
if typ.Kind() == reflect.Float32 {
return reflect.ValueOf(float32(f)), nil
} else if typ.Kind() == reflect.Float64 {
return reflect.ValueOf(f), nil
}
// else, fall through to the error below
}
}
return reflect.Zero(typ), errTypeMismatch(typ, v.Type(), src.GetToken())
}
return v.Convert(typ), nil
Expand Down
10 changes: 9 additions & 1 deletion decode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,10 @@ func TestDecoder(t *testing.T) {
"v: 18446744073709551616",
map[string]float32{"v": float32(math.MaxUint64 + 1)},
},
{
"v: 1e-06",
map[string]float32{"v": 1e-6},
},

// float64
{
Expand All @@ -307,6 +311,10 @@ func TestDecoder(t *testing.T) {
"v: 18446744073709551616",
map[string]float64{"v": float64(math.MaxUint64 + 1)},
},
{
"v: 1e-06",
map[string]float64{"v": 1e-06},
},

// Timestamps
{
Expand Down Expand Up @@ -2932,4 +2940,4 @@ func TestMapKeyCustomUnmarshaler(t *testing.T) {
if val != "value" {
t.Fatalf("expected to have value \"value\", but got %q", val)
}
}
}
20 changes: 20 additions & 0 deletions encode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,16 @@ func TestEncoder(t *testing.T) {
map[string]float32{"v": 0.99},
nil,
},
{
"v: 1e-06\n",
map[string]float32{"v": 1e-06},
nil,
},
{
"v: 1e-06\n",
map[string]float64{"v": 0.000001},
nil,
},
{
"v: 0.123456789\n",
map[string]float64{"v": 0.123456789},
Expand All @@ -100,6 +110,16 @@ func TestEncoder(t *testing.T) {
map[string]float64{"v": 1000000},
nil,
},
{
"v: 1e-06\n",
map[string]float64{"v": 0.000001},
nil,
},
{
"v: 1e-06\n",
map[string]float64{"v": 1e-06},
nil,
},
{
"v: .inf\n",
map[string]interface{}{"v": math.Inf(0)},
Expand Down

0 comments on commit 84014b3

Please sign in to comment.