Skip to content

Commit

Permalink
feat: (ast) support casting V_STRING to number (#262)
Browse files Browse the repository at this point in the history
  • Loading branch information
AsterDY committed Jul 12, 2022
1 parent 07d7b86 commit 755c025
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 18 deletions.
18 changes: 14 additions & 4 deletions ast/node.go
Expand Up @@ -187,13 +187,14 @@ func (self *Node) Bool() (bool, error) {
}
}

// Int64 casts the node to int64 value, including V_NUMBER, V_TRUE, V_FALSE, V_ANY
// Int64 casts the node to int64 value, including V_NUMBER, V_TRUE, V_FALSE, V_ANY,
// V_STRING of invalid digits
func (self *Node) Int64() (int64, error) {
if err := self.checkRaw(); err != nil {
return 0, err
}
switch self.t {
case _V_NUMBER : return numberToInt64(self)
case _V_NUMBER, types.V_STRING : return numberToInt64(self)
case types.V_TRUE : return 1, nil
case types.V_FALSE : return 0, nil
case _V_ANY :
Expand Down Expand Up @@ -241,13 +242,22 @@ func (self *Node) StrictInt64() (int64, error) {
}
}

// Number casts node to float64, including V_NUMBER, V_TRUE, V_FALSE, V_ANY of json.Number
// Number casts node to float64, including V_NUMBER, V_TRUE, V_FALSE, V_ANY of json.Number,
// V_STRING of invalid digits
func (self *Node) Number() (json.Number, error) {
if err := self.checkRaw(); err != nil {
return json.Number(""), err
}
switch self.t {
case _V_NUMBER : return toNumber(self) , nil
case types.V_STRING :
if _, err := numberToInt64(self); err == nil {
return toNumber(self), nil
} else if _, err := numberToFloat64(self); err == nil {
return toNumber(self), nil
} else {
return json.Number(""), err
}
case types.V_TRUE : return json.Number("1"), nil
case types.V_FALSE : return json.Number("0"), nil
case _V_ANY :
Expand Down Expand Up @@ -329,7 +339,7 @@ func (self *Node) Float64() (float64, error) {
return 0.0, err
}
switch self.t {
case _V_NUMBER : return numberToFloat64(self)
case _V_NUMBER, types.V_STRING : return numberToFloat64(self)
case types.V_TRUE : return 1.0, nil
case types.V_FALSE : return 0.0, nil
case _V_ANY :
Expand Down
42 changes: 28 additions & 14 deletions ast/node_test.go
Expand Up @@ -17,18 +17,19 @@
package ast

import (
`encoding/json`
`fmt`
`reflect`
`runtime`
`runtime/debug`
`strconv`
`testing`

`github.com/bytedance/sonic/encoder`
`github.com/bytedance/sonic/internal/native/types`
`github.com/bytedance/sonic/internal/rt`
`github.com/stretchr/testify/assert`
`encoding/json`
`errors`
`fmt`
`reflect`
`runtime`
`runtime/debug`
`strconv`
`testing`

`github.com/bytedance/sonic/encoder`
`github.com/bytedance/sonic/internal/native/types`
`github.com/bytedance/sonic/internal/rt`
`github.com/stretchr/testify/assert`
)


Expand Down Expand Up @@ -232,6 +233,7 @@ func TestTypeCast(t *testing.T) {
exp interface{}
err error
}
var nonEmptyErr error = errors.New("")
a1 := NewAny(1)
lazyArray, _ := NewParser("[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]").Parse()
lazyObject, _ := NewParser(`{"0":0,"1":1,"2":2,"3":3,"4":4,"5":5,"6":6,"7":7,"8":8,"9":9,"10":10,"11":11,"12":12,"13":13,"14":14,"15":15,"16":16}`).Parse()
Expand Down Expand Up @@ -282,6 +284,8 @@ func TestTypeCast(t *testing.T) {
{"Bool", NewRaw("false"), false, nil},
{"Int64", NewRaw("true"), int64(1), nil},
{"Int64", NewRaw("false"), int64(0), nil},
{"Int64", NewRaw("\"1\""), int64(1), nil},
{"Int64", NewRaw("\"1.0\""), int64(0), nonEmptyErr},
{"Int64", NewAny(int(0)), int64(0), nil},
{"Int64", NewAny(int8(0)), int64(0), nil},
{"Int64", NewAny(int16(0)), int64(0), nil},
Expand All @@ -308,6 +312,8 @@ func TestTypeCast(t *testing.T) {
{"StrictInt64", NewRaw("0"), int64(0), nil},
{"Float64", NewRaw("true"), float64(1), nil},
{"Float64", NewRaw("false"), float64(0), nil},
{"Float64", NewRaw("\"1.0\""), float64(1.0), nil},
{"Float64", NewRaw("\"xx\""), float64(0), nonEmptyErr},
{"Float64", Node{}, float64(0), ErrUnsupportType},
{"Float64", NewAny(float32(0)), float64(0), nil},
{"Float64", NewAny(float64(0)), float64(0), nil},
Expand All @@ -321,6 +327,9 @@ func TestTypeCast(t *testing.T) {
{"Number", Node{}, json.Number(""), ErrUnsupportType},
{"Number", NewAny(json.Number("0")), json.Number("0"), nil},
{"Number", NewRaw("0.0"), json.Number("0.0"), nil},
{"Number", NewRaw("\"1\""), json.Number("1"), nil},
{"Number", NewRaw("\"1.1\""), json.Number("1.1"), nil},
{"Number", NewRaw("\"0.x0\""), json.Number(""), nonEmptyErr},
{"Number", NewRaw("true"), json.Number("1"), nil},
{"Number", NewRaw("false"), json.Number("0"), nil},
{"StrictNumber", NewRaw("true"), json.Number(""), ErrUnsupportType},
Expand Down Expand Up @@ -380,8 +389,13 @@ func TestTypeCast(t *testing.T) {
if !reflect.DeepEqual(rets[0].Interface(), c.exp) {
t.Fatal(i, rets[0].Interface(), c.exp)
}
if rets[1].Interface() != c.err {
t.Fatal(i, rets[1].Interface())
v := rets[1].Interface();
if c.err == nonEmptyErr {
if reflect.ValueOf(v).IsNil() {
t.Fatal(i, v)
}
} else if v != c.err {
t.Fatal(i, v)
}
}
}
Expand Down

0 comments on commit 755c025

Please sign in to comment.