From d757f0fb85fe571a32e790ac7671a190c9281992 Mon Sep 17 00:00:00 2001 From: Stepan Pyzhov Date: Tue, 22 Oct 2024 14:52:02 +0200 Subject: [PATCH] #67 Add `is_*type*` functions --- README.md | 11 ++++- cmd/ajson/main.go | 2 +- math.go | 114 ++++++++++++++++++++++++++++++++++++---------- math_test.go | 76 +++++++++++++++++++++++++++++++ 4 files changed, 178 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 5f0adf0..496aab8 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ func main() { You can download `ajson` cli from the [release page](https://github.com/spyzhov/ajson/releases), or install from the source: ```shell script -go get github.com/spyzhov/ajson/cmd/ajson@v0.9.4 +go get github.com/spyzhov/ajson/cmd/ajson@v0.9.5 ``` Usage: @@ -321,6 +321,15 @@ Package has several predefined functions. first Get first element any floor math.Floor integers, floats gamma math.Gamma integers, floats + is_array Is type Array any + is_bool Is type Bool any + is_float Is type Float any + is_int Is type Int any + is_null Is type Null any + is_numeric Is type Numeric any + is_object Is type Object any + is_string Is type String any + is_uint Is type Uint any j0 math.J0 integers, floats j1 math.J1 integers, floats key Key of element string diff --git a/cmd/ajson/main.go b/cmd/ajson/main.go index a29f918..f99179e 100644 --- a/cmd/ajson/main.go +++ b/cmd/ajson/main.go @@ -13,7 +13,7 @@ import ( "github.com/spyzhov/ajson" ) -var version = "v0.9.4" +var version = "v0.9.5" func usage() { text := `` diff --git a/math.go b/math.go index 7087000..5dfa480 100644 --- a/math.go +++ b/math.go @@ -97,21 +97,21 @@ var ( "**": func(left *Node, right *Node) (result *Node, err error) { lnum, rnum, err := _floats(left, right) if err != nil { - return + return nil, err } return valueNode(nil, "power", Numeric, math.Pow(lnum, rnum)), nil }, "*": func(left *Node, right *Node) (result *Node, err error) { lnum, rnum, err := _floats(left, right) if err != nil { - return + return nil, err } return valueNode(nil, "multiply", Numeric, float64(lnum*rnum)), nil }, "/": func(left *Node, right *Node) (result *Node, err error) { lnum, rnum, err := _floats(left, right) if err != nil { - return + return nil, err } if rnum == 0 { return nil, errorRequest("division by zero") @@ -121,47 +121,47 @@ var ( "%": func(left *Node, right *Node) (result *Node, err error) { lnum, err := left.getInteger() if err != nil { - return + return nil, err } rnum, err := right.getInteger() if err != nil { - return + return nil, err } return valueNode(nil, "remainder", Numeric, float64(lnum%rnum)), nil }, "<<": func(left *Node, right *Node) (result *Node, err error) { lnum, err := left.getInteger() if err != nil { - return + return nil, err } rnum, err := right.getUInteger() if err != nil { - return + return nil, err } return valueNode(nil, "left shift", Numeric, float64(lnum<>": func(left *Node, right *Node) (result *Node, err error) { lnum, err := left.getInteger() if err != nil { - return + return nil, err } rnum, err := right.getUInteger() if err != nil { - return + return nil, err } return valueNode(nil, "right shift", Numeric, float64(lnum>>rnum)), nil }, "&": func(left *Node, right *Node) (result *Node, err error) { lnum, rnum, err := _ints(left, right) if err != nil { - return + return nil, err } return valueNode(nil, "bitwise AND", Numeric, float64(lnum&rnum)), nil }, "&^": func(left *Node, right *Node) (result *Node, err error) { lnum, rnum, err := _ints(left, right) if err != nil { - return + return nil, err } return valueNode(nil, "bit clear (AND NOT)", Numeric, float64(lnum&^rnum)), nil }, @@ -182,14 +182,14 @@ var ( "-": func(left *Node, right *Node) (result *Node, err error) { lnum, rnum, err := _floats(left, right) if err != nil { - return + return nil, err } return valueNode(nil, "sub", Numeric, float64(lnum-rnum)), nil }, "|": func(left *Node, right *Node) (result *Node, err error) { lnum, rnum, err := _ints(left, right) if err != nil { - return + return nil, err } return valueNode(nil, "bitwise OR", Numeric, float64(lnum|rnum)), nil }, @@ -355,7 +355,7 @@ var ( } num, err := node.getInteger() if err != nil { - return + return nil, err } return valueNode(nil, "Pow10", Numeric, float64(math.Pow10(num))), nil }, @@ -384,7 +384,7 @@ var ( } num, err := node.getUInteger() if err != nil { - return + return nil, err } return valueNode(nil, "factorial", Numeric, float64(mathFactorial(num))), nil }, @@ -445,9 +445,9 @@ var ( if remainder != 0 { size += 1 + remainder } - var result []byte = make([]byte, size) - base64.StdEncoding.WithPadding(base64.NoPadding).Encode(result, []byte(sourceString)) - return valueNode(nil, "b64encoden", String, string(result)), nil + var bytes = make([]byte, size) + base64.StdEncoding.WithPadding(base64.NoPadding).Encode(bytes, []byte(sourceString)) + return valueNode(nil, "b64encoden", String, string(bytes)), nil } } return valueNode(nil, "b64encoden", Null, nil), nil @@ -462,9 +462,9 @@ var ( if remainder != 0 { size += 4 } - var result []byte = make([]byte, size) - base64.StdEncoding.WithPadding(base64.StdPadding).Encode(result, []byte(sourceString)) - return valueNode(nil, "b64encode", String, string(result)), nil + var bytes = make([]byte, size) + base64.StdEncoding.WithPadding(base64.StdPadding).Encode(bytes, []byte(sourceString)) + return valueNode(nil, "b64encode", String, string(bytes)), nil } } return valueNode(nil, "b64encode", Null, nil), nil @@ -510,7 +510,7 @@ var ( } num, err := node.GetNumeric() if err != nil { - return + return nil, err } return valueNode(nil, "Rand", Numeric, randFunc()*num), nil }, @@ -520,7 +520,7 @@ var ( } num, err := node.getInteger() if err != nil { - return + return nil, err } return valueNode(nil, "RandInt", Numeric, float64(randIntFunc(num))), nil }, @@ -572,6 +572,74 @@ var ( } return valueNode(nil, "key", Null, nil), nil }, + "is_null": func(node *Node) (result *Node, err error) { + if node == nil { + return valueNode(nil, "is_null", Null, nil), nil + } + return valueNode(nil, "is_null", Bool, node.IsNull()), nil + }, + "is_numeric": func(node *Node) (result *Node, err error) { + if node == nil { + return valueNode(nil, "is_numeric", Null, nil), nil + } + return valueNode(nil, "is_numeric", Bool, node.IsNumeric()), nil + }, + "is_int": func(node *Node) (result *Node, err error) { + if node == nil { + return valueNode(nil, "is_int", Null, nil), nil + } + _, err = node.getInteger() + if err != nil { + return valueNode(nil, "is_int", Bool, false), nil + } + return valueNode(nil, "is_int", Bool, true), nil + }, + "is_uint": func(node *Node) (result *Node, err error) { + if node == nil { + return valueNode(nil, "is_uint", Null, nil), nil + } + _, err = node.getUInteger() + if err != nil { + return valueNode(nil, "is_uint", Bool, false), nil + } + return valueNode(nil, "is_uint", Bool, true), nil + }, + "is_float": func(node *Node) (result *Node, err error) { + if node == nil { + return valueNode(nil, "is_float", Null, nil), nil + } + if node.IsNumeric() { + _, err = node.getInteger() + if err != nil { + return valueNode(nil, "is_float", Bool, true), nil + } + } + return valueNode(nil, "is_float", Bool, false), nil + }, + "is_string": func(node *Node) (result *Node, err error) { + if node == nil { + return valueNode(nil, "is_string", Null, nil), nil + } + return valueNode(nil, "is_string", Bool, node.IsString()), nil + }, + "is_bool": func(node *Node) (result *Node, err error) { + if node == nil { + return valueNode(nil, "is_bool", Null, nil), nil + } + return valueNode(nil, "is_bool", Bool, node.IsBool()), nil + }, + "is_array": func(node *Node) (result *Node, err error) { + if node == nil { + return valueNode(nil, "is_array", Null, nil), nil + } + return valueNode(nil, "is_array", Bool, node.IsArray()), nil + }, + "is_object": func(node *Node) (result *Node, err error) { + if node == nil { + return valueNode(nil, "is_object", Null, nil), nil + } + return valueNode(nil, "is_object", Bool, node.IsObject()), nil + }, } constants = map[string]*Node{ diff --git a/math_test.go b/math_test.go index 73bf747..beee6e0 100644 --- a/math_test.go +++ b/math_test.go @@ -565,6 +565,82 @@ func TestFunctions2(t *testing.T) { {name: "key", fname: "key", value: key, result: StringNode("", "t"), fail: false}, {name: "key: none", fname: "key", value: StringNode("", "value"), result: NullNode(""), fail: false}, {name: "key nil", fname: "key", value: nil, result: NullNode("")}, + + {name: "is_null nil", fname: "is_null", value: nil, result: NullNode("")}, + {name: "is_null null", fname: "is_null", value: NullNode(""), result: BoolNode("", true)}, + {name: "is_null str", fname: "is_null", value: StringNode("", ""), result: BoolNode("", false)}, + {name: "is_numeric nil", fname: "is_numeric", value: nil, result: NullNode("")}, + {name: "is_numeric null", fname: "is_numeric", value: NullNode(""), result: BoolNode("", false)}, + {name: "is_numeric int", fname: "is_numeric", value: NumericNode("", -123), result: BoolNode("", true)}, + {name: "is_numeric uint", fname: "is_numeric", value: NumericNode("", 123), result: BoolNode("", true)}, + {name: "is_numeric float", fname: "is_numeric", value: NumericNode("", -12.34), result: BoolNode("", true)}, + {name: "is_numeric string", fname: "is_numeric", value: StringNode("", ""), result: BoolNode("", false)}, + {name: "is_numeric bool", fname: "is_numeric", value: BoolNode("", true), result: BoolNode("", false)}, + {name: "is_numeric array", fname: "is_numeric", value: ArrayNode("", nil), result: BoolNode("", false)}, + {name: "is_numeric object", fname: "is_numeric", value: ObjectNode("", nil), result: BoolNode("", false)}, + {name: "is_int nil", fname: "is_int", value: nil, result: NullNode("")}, + {name: "is_int null", fname: "is_int", value: NullNode(""), result: BoolNode("", false)}, + {name: "is_int int", fname: "is_int", value: NumericNode("", -123), result: BoolNode("", true)}, + {name: "is_int uint", fname: "is_int", value: NumericNode("", 123), result: BoolNode("", true)}, + {name: "is_int float", fname: "is_int", value: NumericNode("", -12.34), result: BoolNode("", false)}, + {name: "is_int string", fname: "is_int", value: StringNode("", ""), result: BoolNode("", false)}, + {name: "is_int bool", fname: "is_int", value: BoolNode("", true), result: BoolNode("", false)}, + {name: "is_int array", fname: "is_int", value: ArrayNode("", nil), result: BoolNode("", false)}, + {name: "is_int object", fname: "is_int", value: ObjectNode("", nil), result: BoolNode("", false)}, + {name: "is_uint nil", fname: "is_uint", value: nil, result: NullNode("")}, + {name: "is_uint null", fname: "is_uint", value: NullNode(""), result: BoolNode("", false)}, + {name: "is_uint int", fname: "is_uint", value: NumericNode("", -123), result: BoolNode("", false)}, + {name: "is_uint uint", fname: "is_uint", value: NumericNode("", 123), result: BoolNode("", true)}, + {name: "is_uint float", fname: "is_uint", value: NumericNode("", -12.34), result: BoolNode("", false)}, + {name: "is_uint string", fname: "is_uint", value: StringNode("", ""), result: BoolNode("", false)}, + {name: "is_uint bool", fname: "is_uint", value: BoolNode("", true), result: BoolNode("", false)}, + {name: "is_uint array", fname: "is_uint", value: ArrayNode("", nil), result: BoolNode("", false)}, + {name: "is_uint object", fname: "is_uint", value: ObjectNode("", nil), result: BoolNode("", false)}, + {name: "is_float nil", fname: "is_float", value: nil, result: NullNode("")}, + {name: "is_float null", fname: "is_float", value: NullNode(""), result: BoolNode("", false)}, + {name: "is_float int", fname: "is_float", value: NumericNode("", -123), result: BoolNode("", false)}, + {name: "is_float uint", fname: "is_float", value: NumericNode("", 123), result: BoolNode("", false)}, + {name: "is_float float", fname: "is_float", value: NumericNode("", -12.34), result: BoolNode("", true)}, + {name: "is_float string", fname: "is_float", value: StringNode("", ""), result: BoolNode("", false)}, + {name: "is_float bool", fname: "is_float", value: BoolNode("", true), result: BoolNode("", false)}, + {name: "is_float array", fname: "is_float", value: ArrayNode("", nil), result: BoolNode("", false)}, + {name: "is_float object", fname: "is_float", value: ObjectNode("", nil), result: BoolNode("", false)}, + {name: "is_string nil", fname: "is_string", value: nil, result: NullNode("")}, + {name: "is_string null", fname: "is_string", value: NullNode(""), result: BoolNode("", false)}, + {name: "is_string int", fname: "is_string", value: NumericNode("", -123), result: BoolNode("", false)}, + {name: "is_string uint", fname: "is_string", value: NumericNode("", 123), result: BoolNode("", false)}, + {name: "is_string float", fname: "is_string", value: NumericNode("", -12.34), result: BoolNode("", false)}, + {name: "is_string string", fname: "is_string", value: StringNode("", ""), result: BoolNode("", true)}, + {name: "is_string bool", fname: "is_string", value: BoolNode("", true), result: BoolNode("", false)}, + {name: "is_string array", fname: "is_string", value: ArrayNode("", nil), result: BoolNode("", false)}, + {name: "is_string object", fname: "is_string", value: ObjectNode("", nil), result: BoolNode("", false)}, + {name: "is_bool nil", fname: "is_bool", value: nil, result: NullNode("")}, + {name: "is_bool null", fname: "is_bool", value: NullNode(""), result: BoolNode("", false)}, + {name: "is_bool int", fname: "is_bool", value: NumericNode("", -123), result: BoolNode("", false)}, + {name: "is_bool uint", fname: "is_bool", value: NumericNode("", 123), result: BoolNode("", false)}, + {name: "is_bool float", fname: "is_bool", value: NumericNode("", -12.34), result: BoolNode("", false)}, + {name: "is_bool string", fname: "is_bool", value: StringNode("", ""), result: BoolNode("", false)}, + {name: "is_bool bool", fname: "is_bool", value: BoolNode("", true), result: BoolNode("", true)}, + {name: "is_bool array", fname: "is_bool", value: ArrayNode("", nil), result: BoolNode("", false)}, + {name: "is_bool object", fname: "is_bool", value: ObjectNode("", nil), result: BoolNode("", false)}, + {name: "is_array nil", fname: "is_array", value: nil, result: NullNode("")}, + {name: "is_array null", fname: "is_array", value: NullNode(""), result: BoolNode("", false)}, + {name: "is_array int", fname: "is_array", value: NumericNode("", -123), result: BoolNode("", false)}, + {name: "is_array uint", fname: "is_array", value: NumericNode("", 123), result: BoolNode("", false)}, + {name: "is_array float", fname: "is_array", value: NumericNode("", -12.34), result: BoolNode("", false)}, + {name: "is_array string", fname: "is_array", value: StringNode("", ""), result: BoolNode("", false)}, + {name: "is_array bool", fname: "is_array", value: BoolNode("", true), result: BoolNode("", false)}, + {name: "is_array array", fname: "is_array", value: ArrayNode("", nil), result: BoolNode("", true)}, + {name: "is_array object", fname: "is_array", value: ObjectNode("", nil), result: BoolNode("", false)}, + {name: "is_object nil", fname: "is_object", value: nil, result: NullNode("")}, + {name: "is_object null", fname: "is_object", value: NullNode(""), result: BoolNode("", false)}, + {name: "is_object int", fname: "is_object", value: NumericNode("", -123), result: BoolNode("", false)}, + {name: "is_object uint", fname: "is_object", value: NumericNode("", 123), result: BoolNode("", false)}, + {name: "is_object float", fname: "is_object", value: NumericNode("", -12.34), result: BoolNode("", false)}, + {name: "is_object string", fname: "is_object", value: StringNode("", ""), result: BoolNode("", false)}, + {name: "is_object bool", fname: "is_object", value: BoolNode("", true), result: BoolNode("", false)}, + {name: "is_object array", fname: "is_object", value: ArrayNode("", nil), result: BoolNode("", false)}, + {name: "is_object object", fname: "is_object", value: ObjectNode("", nil), result: BoolNode("", true)}, } for _, test := range tests { t.Run(test.name, func(t *testing.T) {