Fix stylecheck warnings
This commit is contained in:
parent
ca047193ee
commit
3697f12c5c
@ -6,6 +6,7 @@ linters:
|
|||||||
- gochecknoglobals
|
- gochecknoglobals
|
||||||
- gocritic
|
- gocritic
|
||||||
- funlen
|
- funlen
|
||||||
|
- godox
|
||||||
linters-settings:
|
linters-settings:
|
||||||
lll:
|
lll:
|
||||||
line-length: 180
|
line-length: 180
|
||||||
@ -21,4 +22,6 @@ issues:
|
|||||||
- lll
|
- lll
|
||||||
- goconst
|
- goconst
|
||||||
- unparam
|
- unparam
|
||||||
- unused
|
- unused
|
||||||
|
max-issues-per-linter: 0
|
||||||
|
max-same-issues: 0
|
14
eval.go
14
eval.go
@ -259,17 +259,17 @@ func pathEndValue(q *query, e *Eval, i *Item) queryStateFn {
|
|||||||
|
|
||||||
switch q.firstType {
|
switch q.firstType {
|
||||||
case jsonBraceLeft:
|
case jsonBraceLeft:
|
||||||
r.Type = JsonObject
|
r.Type = JSONObject
|
||||||
case jsonString:
|
case jsonString:
|
||||||
r.Type = JsonString
|
r.Type = JSONString
|
||||||
case jsonBracketLeft:
|
case jsonBracketLeft:
|
||||||
r.Type = JsonArray
|
r.Type = JSONArray
|
||||||
case jsonNull:
|
case jsonNull:
|
||||||
r.Type = JsonNull
|
r.Type = JSONNull
|
||||||
case jsonBool:
|
case jsonBool:
|
||||||
r.Type = JsonBool
|
r.Type = JSONBool
|
||||||
case jsonNumber:
|
case jsonNumber:
|
||||||
r.Type = JsonNumber
|
r.Type = JSONNumber
|
||||||
default:
|
default:
|
||||||
r.Type = -1
|
r.Type = -1
|
||||||
}
|
}
|
||||||
@ -297,7 +297,7 @@ func (b *exprBucket) evaluate() (bool, error) {
|
|||||||
for _, q := range b.queries {
|
for _, q := range b.queries {
|
||||||
result := q.resultQueue.Pop()
|
result := q.resultQueue.Pop()
|
||||||
if result != nil {
|
if result != nil {
|
||||||
t, err := getJsonTokenType(result.Value)
|
t, err := getJSONTokenType(result.Value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
48
eval_test.go
48
eval_test.go
@ -15,32 +15,32 @@ type test struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var tests = []test{
|
var tests = []test{
|
||||||
{`key selection`, `{"aKey":32}`, `$.aKey+`, []Result{newResult(`32`, JsonNumber, `aKey`)}},
|
{`key selection`, `{"aKey":32}`, `$.aKey+`, []Result{newResult(`32`, JSONNumber, `aKey`)}},
|
||||||
{`nested key selection`, `{"aKey":{"bKey":32}}`, `$.aKey+`, []Result{newResult(`{"bKey":32}`, JsonObject, `aKey`)}},
|
{`nested key selection`, `{"aKey":{"bKey":32}}`, `$.aKey+`, []Result{newResult(`{"bKey":32}`, JSONObject, `aKey`)}},
|
||||||
{`empty array`, `{"aKey":[]}`, `$.aKey+`, []Result{newResult(`[]`, JsonArray, `aKey`)}},
|
{`empty array`, `{"aKey":[]}`, `$.aKey+`, []Result{newResult(`[]`, JSONArray, `aKey`)}},
|
||||||
{`multiple same-level keys, weird spacing`, `{ "aKey" : true , "bKey": [ 1 , 2 ], "cKey" : true } `, `$.bKey+`, []Result{newResult(`[1,2]`, JsonArray, `bKey`)}},
|
{`multiple same-level keys, weird spacing`, `{ "aKey" : true , "bKey": [ 1 , 2 ], "cKey" : true } `, `$.bKey+`, []Result{newResult(`[1,2]`, JSONArray, `bKey`)}},
|
||||||
|
|
||||||
{`array index selection`, `{"aKey":[123,456]}`, `$.aKey[1]+`, []Result{newResult(`456`, JsonNumber, `aKey`, 1)}},
|
{`array index selection`, `{"aKey":[123,456]}`, `$.aKey[1]+`, []Result{newResult(`456`, JSONNumber, `aKey`, 1)}},
|
||||||
{`array wild index selection`, `{"aKey":[123,456]}`, `$.aKey[*]+`, []Result{newResult(`123`, JsonNumber, `aKey`, 0), newResult(`456`, JsonNumber, `aKey`, 1)}},
|
{`array wild index selection`, `{"aKey":[123,456]}`, `$.aKey[*]+`, []Result{newResult(`123`, JSONNumber, `aKey`, 0), newResult(`456`, JSONNumber, `aKey`, 1)}},
|
||||||
{`array range index selection`, `{"aKey":[11,22,33,44]}`, `$.aKey[1:3]+`, []Result{newResult(`22`, JsonNumber, `aKey`, 1), newResult(`33`, JsonNumber, `aKey`, 2)}},
|
{`array range index selection`, `{"aKey":[11,22,33,44]}`, `$.aKey[1:3]+`, []Result{newResult(`22`, JSONNumber, `aKey`, 1), newResult(`33`, JSONNumber, `aKey`, 2)}},
|
||||||
{`array range (no index) selection`, `{"aKey":[11,22,33,44]}`, `$.aKey[1:1]+`, []Result{}},
|
{`array range (no index) selection`, `{"aKey":[11,22,33,44]}`, `$.aKey[1:1]+`, []Result{}},
|
||||||
{`array range (no upper bound) selection`, `{"aKey":[11,22,33]}`, `$.aKey[1:]+`, []Result{newResult(`22`, JsonNumber, `aKey`, 1), newResult(`33`, JsonNumber, `aKey`, 2)}},
|
{`array range (no upper bound) selection`, `{"aKey":[11,22,33]}`, `$.aKey[1:]+`, []Result{newResult(`22`, JSONNumber, `aKey`, 1), newResult(`33`, JSONNumber, `aKey`, 2)}},
|
||||||
|
|
||||||
{`empty array - try selection`, `{"aKey":[]}`, `$.aKey[1]+`, []Result{}},
|
{`empty array - try selection`, `{"aKey":[]}`, `$.aKey[1]+`, []Result{}},
|
||||||
{`null selection`, `{"aKey":[null]}`, `$.aKey[0]+`, []Result{newResult(`null`, JsonNull, `aKey`, 0)}},
|
{`null selection`, `{"aKey":[null]}`, `$.aKey[0]+`, []Result{newResult(`null`, JSONNull, `aKey`, 0)}},
|
||||||
{`empty object`, `{"aKey":{}}`, `$.aKey+`, []Result{newResult(`{}`, JsonObject, `aKey`)}},
|
{`empty object`, `{"aKey":{}}`, `$.aKey+`, []Result{newResult(`{}`, JSONObject, `aKey`)}},
|
||||||
{`object w/ height=2`, `{"aKey":{"bKey":32}}`, `$.aKey.bKey+`, []Result{newResult(`32`, JsonNumber, `aKey`, `bKey`)}},
|
{`object w/ height=2`, `{"aKey":{"bKey":32}}`, `$.aKey.bKey+`, []Result{newResult(`32`, JSONNumber, `aKey`, `bKey`)}},
|
||||||
{`array of multiple types`, `{"aKey":[1,{"s":true},"asdf"]}`, `$.aKey[1]+`, []Result{newResult(`{"s":true}`, JsonObject, `aKey`, 1)}},
|
{`array of multiple types`, `{"aKey":[1,{"s":true},"asdf"]}`, `$.aKey[1]+`, []Result{newResult(`{"s":true}`, JSONObject, `aKey`, 1)}},
|
||||||
{`nested array selection`, `{"aKey":{"bKey":[123,456]}}`, `$.aKey.bKey+`, []Result{newResult(`[123,456]`, JsonArray, `aKey`, `bKey`)}},
|
{`nested array selection`, `{"aKey":{"bKey":[123,456]}}`, `$.aKey.bKey+`, []Result{newResult(`[123,456]`, JSONArray, `aKey`, `bKey`)}},
|
||||||
{`nested array`, `[[[[[]], [true, false, []]]]]`, `$[0][0][1][2]+`, []Result{newResult(`[]`, JsonArray, 0, 0, 1, 2)}},
|
{`nested array`, `[[[[[]], [true, false, []]]]]`, `$[0][0][1][2]+`, []Result{newResult(`[]`, JSONArray, 0, 0, 1, 2)}},
|
||||||
{`index of array selection`, `{"aKey":{"bKey":[123, 456, 789]}}`, `$.aKey.bKey[1]+`, []Result{newResult(`456`, JsonNumber, `aKey`, `bKey`, 1)}},
|
{`index of array selection`, `{"aKey":{"bKey":[123, 456, 789]}}`, `$.aKey.bKey[1]+`, []Result{newResult(`456`, JSONNumber, `aKey`, `bKey`, 1)}},
|
||||||
{`index of array selection (more than one)`, `{"aKey":{"bKey":[123,456]}}`, `$.aKey.bKey[1]+`, []Result{newResult(`456`, JsonNumber, `aKey`, `bKey`, 1)}},
|
{`index of array selection (more than one)`, `{"aKey":{"bKey":[123,456]}}`, `$.aKey.bKey[1]+`, []Result{newResult(`456`, JSONNumber, `aKey`, `bKey`, 1)}},
|
||||||
{`multi-level object/array`, `{"1Key":{"aKey": null, "bKey":{"trash":[1,2]}, "cKey":[123,456] }, "2Key":false}`, `$.1Key.bKey.trash[0]+`, []Result{newResult(`1`, JsonNumber, `1Key`, `bKey`, `trash`, 0)}},
|
{`multi-level object/array`, `{"1Key":{"aKey": null, "bKey":{"trash":[1,2]}, "cKey":[123,456] }, "2Key":false}`, `$.1Key.bKey.trash[0]+`, []Result{newResult(`1`, JSONNumber, `1Key`, `bKey`, `trash`, 0)}},
|
||||||
{`multi-level array`, `{"aKey":[true,false,null,{"michael":[5,6,7]}, ["s", "3"] ]}`, `$.*[*].michael[1]+`, []Result{newResult(`6`, JsonNumber, `aKey`, 3, `michael`, 1)}},
|
{`multi-level array`, `{"aKey":[true,false,null,{"michael":[5,6,7]}, ["s", "3"] ]}`, `$.*[*].michael[1]+`, []Result{newResult(`6`, JSONNumber, `aKey`, 3, `michael`, 1)}},
|
||||||
{`multi-level array 2`, `{"aKey":[true,false,null,{"michael":[5,6,7]}, ["s", "3"] ]}`, `$.*[*][1]+`, []Result{newResult(`"3"`, JsonString, `aKey`, 4, 1)}},
|
{`multi-level array 2`, `{"aKey":[true,false,null,{"michael":[5,6,7]}, ["s", "3"] ]}`, `$.*[*][1]+`, []Result{newResult(`"3"`, JSONString, `aKey`, 4, 1)}},
|
||||||
|
|
||||||
{`evaluation literal equality`, `{"items":[ {"name":"alpha", "value":11}]}`, `$.items[*]?("bravo" == "bravo").value+`, []Result{newResult(`11`, JsonNumber, `items`, 0, `value`)}},
|
{`evaluation literal equality`, `{"items":[ {"name":"alpha", "value":11}]}`, `$.items[*]?("bravo" == "bravo").value+`, []Result{newResult(`11`, JSONNumber, `items`, 0, `value`)}},
|
||||||
{`evaluation based on string equal to path value`, `{"items":[ {"name":"alpha", "value":11}, {"name":"bravo", "value":22}, {"name":"charlie", "value":33} ]}`, `$.items[*]?(@.name == "bravo").value+`, []Result{newResult(`22`, JsonNumber, `items`, 1, `value`)}},
|
{`evaluation based on string equal to path value`, `{"items":[ {"name":"alpha", "value":11}, {"name":"bravo", "value":22}, {"name":"charlie", "value":33} ]}`, `$.items[*]?(@.name == "bravo").value+`, []Result{newResult(`22`, JSONNumber, `items`, 1, `value`)}},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPathQuery(t *testing.T) {
|
func TestPathQuery(t *testing.T) {
|
||||||
@ -52,14 +52,16 @@ func TestPathQuery(t *testing.T) {
|
|||||||
eval, err := EvalPathsInBytes([]byte(t.json), paths)
|
eval, err := EvalPathsInBytes([]byte(t.json), paths)
|
||||||
if as.NoError(err, "Testing: %s", t.name) {
|
if as.NoError(err, "Testing: %s", t.name) {
|
||||||
res := toResultArray(eval)
|
res := toResultArray(eval)
|
||||||
|
|
||||||
if as.NoError(eval.Error) {
|
if as.NoError(eval.Error) {
|
||||||
as.EqualValues(t.expected, res, "Testing of %q", t.name)
|
as.EqualValues(t.expected, res, "Testing of %q", t.name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
eval_reader, err := EvalPathsInReader(strings.NewReader(t.json), paths)
|
evalReader, err := EvalPathsInReader(strings.NewReader(t.json), paths)
|
||||||
if as.NoError(err, "Testing: %s", t.name) {
|
if as.NoError(err, "Testing: %s", t.name) {
|
||||||
res := toResultArray(eval_reader)
|
res := toResultArray(evalReader)
|
||||||
|
|
||||||
if as.NoError(eval.Error) {
|
if as.NoError(eval.Error) {
|
||||||
as.EqualValues(t.expected, res, "Testing of %q", t.name)
|
as.EqualValues(t.expected, res, "Testing of %q", t.name)
|
||||||
}
|
}
|
||||||
|
@ -64,11 +64,11 @@ func infixToPostFix(items []Item) (out []Item, err error) {
|
|||||||
found := false
|
found := false
|
||||||
for {
|
for {
|
||||||
// pop item ("(" or operator) from stack
|
// pop item ("(" or operator) from stack
|
||||||
op_interface, ok := stack.pop()
|
opInterface, ok := stack.pop()
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.New(exprErrorMismatchedParens)
|
return nil, errors.New(exprErrorMismatchedParens)
|
||||||
}
|
}
|
||||||
op := op_interface.(Item)
|
op := opInterface.(Item)
|
||||||
if op.typ == exprParenLeft {
|
if op.typ == exprParenLeft {
|
||||||
found = true
|
found = true
|
||||||
break // discard "("
|
break // discard "("
|
||||||
@ -83,8 +83,8 @@ func infixToPostFix(items []Item) (out []Item, err error) {
|
|||||||
// token is an operator
|
// token is an operator
|
||||||
for stack.len() > 0 {
|
for stack.len() > 0 {
|
||||||
// consider top item on stack
|
// consider top item on stack
|
||||||
op_int, _ := stack.peek()
|
opInt, _ := stack.peek()
|
||||||
op := op_int.(Item)
|
op := opInt.(Item)
|
||||||
if o2, isOp := opa[op.typ]; !isOp || o1.prec > o2.prec ||
|
if o2, isOp := opa[op.typ]; !isOp || o1.prec > o2.prec ||
|
||||||
o1.prec == o2.prec && o1.rAssoc {
|
o1.prec == o2.prec && o1.rAssoc {
|
||||||
break
|
break
|
||||||
@ -102,8 +102,8 @@ func infixToPostFix(items []Item) (out []Item, err error) {
|
|||||||
}
|
}
|
||||||
// drain stack to result
|
// drain stack to result
|
||||||
for stack.len() > 0 {
|
for stack.len() > 0 {
|
||||||
op_int, _ := stack.pop()
|
opInt, _ := stack.pop()
|
||||||
op := op_int.(Item)
|
op := opInt.(Item)
|
||||||
if op.typ == exprParenLeft {
|
if op.typ == exprParenLeft {
|
||||||
return nil, errors.New(exprErrorMismatchedParens)
|
return nil, errors.New(exprErrorMismatchedParens)
|
||||||
}
|
}
|
||||||
@ -308,7 +308,7 @@ func evaluatePostFix(postFixItems []Item, pathValues map[string]Item) (interface
|
|||||||
}
|
}
|
||||||
|
|
||||||
if a == 0.0 {
|
if a == 0.0 {
|
||||||
return false, errors.New("Cannot divide by zero")
|
return false, errors.New("cannot divide by zero")
|
||||||
}
|
}
|
||||||
s.push(b / a)
|
s.push(b / a)
|
||||||
case exprOpStar:
|
case exprOpStar:
|
||||||
@ -340,15 +340,16 @@ func evaluatePostFix(postFixItems []Item, pathValues map[string]Item) (interface
|
|||||||
s.push(!a)
|
s.push(!a)
|
||||||
// Other
|
// Other
|
||||||
default:
|
default:
|
||||||
return false, fmt.Errorf("Token not supported in evaluator: %v", exprTokenNames[item.typ])
|
return false, fmt.Errorf("token not supported in evaluator: %v", exprTokenNames[item.typ])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.len() != 1 {
|
if s.len() != 1 {
|
||||||
return false, fmt.Errorf(exprErrorBadExpression)
|
return false, fmt.Errorf(exprErrorBadExpression)
|
||||||
}
|
}
|
||||||
end_int, _ := s.pop()
|
|
||||||
return end_int, nil
|
endInt, _ := s.pop()
|
||||||
|
return endInt, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func take1Bool(s *stack, op int) (bool, error) {
|
func take1Bool(s *stack, op int) (bool, error) {
|
||||||
|
@ -38,12 +38,14 @@ var jsonTokenNames = map[int]string{
|
|||||||
jsonBool: "BOOL",
|
jsonBool: "BOOL",
|
||||||
}
|
}
|
||||||
|
|
||||||
var JSON = lexJsonRoot
|
var JSON = lexJSONRoot
|
||||||
|
|
||||||
func lexJsonRoot(l lexer, state *intStack) stateFn {
|
func lexJSONRoot(l lexer, state *intStack) stateFn {
|
||||||
ignoreSpaceRun(l)
|
ignoreSpaceRun(l)
|
||||||
cur := l.peek()
|
cur := l.peek()
|
||||||
|
|
||||||
var next stateFn
|
var next stateFn
|
||||||
|
|
||||||
switch cur {
|
switch cur {
|
||||||
case '{':
|
case '{':
|
||||||
next = stateJSONObjectOpen
|
next = stateJSONObjectOpen
|
||||||
|
@ -33,7 +33,7 @@ func TestValidJson(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var errorJsonTests = []lexTest{
|
var errorJSONTests = []lexTest{
|
||||||
{"Missing end brace", `{`, []int{jsonBraceLeft, jsonError}},
|
{"Missing end brace", `{`, []int{jsonBraceLeft, jsonError}},
|
||||||
{"Missing start brace", `}`, []int{jsonError}},
|
{"Missing start brace", `}`, []int{jsonError}},
|
||||||
{"Missing key start quote", `{key":true}`, []int{jsonBraceLeft, jsonError}},
|
{"Missing key start quote", `{key":true}`, []int{jsonBraceLeft, jsonError}},
|
||||||
@ -50,7 +50,7 @@ var errorJsonTests = []lexTest{
|
|||||||
func TestMalformedJson(t *testing.T) {
|
func TestMalformedJson(t *testing.T) {
|
||||||
as := assert.New(t)
|
as := assert.New(t)
|
||||||
|
|
||||||
for _, test := range errorJsonTests {
|
for _, test := range errorJSONTests {
|
||||||
lexer := NewSliceLexer([]byte(test.input), JSON)
|
lexer := NewSliceLexer([]byte(test.input), JSON)
|
||||||
types := itemsToTypes(readerToArray(lexer))
|
types := itemsToTypes(readerToArray(lexer))
|
||||||
|
|
||||||
|
@ -34,14 +34,14 @@ func (l *SliceLexer) takeString() error {
|
|||||||
inputLen := len(l.input)
|
inputLen := len(l.input)
|
||||||
|
|
||||||
if int(curPos) >= inputLen {
|
if int(curPos) >= inputLen {
|
||||||
return errors.New("End of file where string expected")
|
return errors.New("end of file where string expected")
|
||||||
}
|
}
|
||||||
|
|
||||||
cur := int(l.input[curPos])
|
cur := int(l.input[curPos])
|
||||||
curPos++
|
curPos++
|
||||||
if cur != '"' {
|
if cur != '"' {
|
||||||
l.pos = curPos
|
l.pos = curPos
|
||||||
return fmt.Errorf("Expected \" as start of string instead of %#U", cur)
|
return fmt.Errorf("expected \" as start of string instead of %#U", cur)
|
||||||
}
|
}
|
||||||
|
|
||||||
var previous int
|
var previous int
|
||||||
@ -49,7 +49,7 @@ looper:
|
|||||||
for {
|
for {
|
||||||
if int(curPos) >= inputLen {
|
if int(curPos) >= inputLen {
|
||||||
l.pos = curPos
|
l.pos = curPos
|
||||||
return errors.New("End of file where string expected")
|
return errors.New("end of file where string expected")
|
||||||
}
|
}
|
||||||
cur := int(l.input[curPos])
|
cur := int(l.input[curPos])
|
||||||
curPos++
|
curPos++
|
||||||
|
17
misc.go
17
misc.go
@ -16,13 +16,13 @@ func takeExponent(l lexer) error {
|
|||||||
case '+', '-':
|
case '+', '-':
|
||||||
// Check digit immediately follows sign
|
// Check digit immediately follows sign
|
||||||
if d := l.peek(); !(d >= '0' && d <= '9') {
|
if d := l.peek(); !(d >= '0' && d <= '9') {
|
||||||
return fmt.Errorf("Expected digit after numeric sign instead of %#U", d)
|
return fmt.Errorf("expected digit after numeric sign instead of %#U", d)
|
||||||
}
|
}
|
||||||
takeDigits(l)
|
takeDigits(l)
|
||||||
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||||
takeDigits(l)
|
takeDigits(l)
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("Expected digit after 'e' instead of %#U", r)
|
return fmt.Errorf("expected digit after 'e' instead of %#U", r)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -33,13 +33,13 @@ func takeJSONNumeric(l lexer) error {
|
|||||||
case '-':
|
case '-':
|
||||||
// Check digit immediately follows sign
|
// Check digit immediately follows sign
|
||||||
if d := l.peek(); !(d >= '0' && d <= '9') {
|
if d := l.peek(); !(d >= '0' && d <= '9') {
|
||||||
return fmt.Errorf("Expected digit after dash instead of %#U", d)
|
return fmt.Errorf("expected digit after dash instead of %#U", d)
|
||||||
}
|
}
|
||||||
takeDigits(l)
|
takeDigits(l)
|
||||||
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||||
takeDigits(l)
|
takeDigits(l)
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("Expected digit or dash instead of %#U", cur)
|
return fmt.Errorf("expected digit or dash instead of %#U", cur)
|
||||||
}
|
}
|
||||||
|
|
||||||
// fraction or exponent
|
// fraction or exponent
|
||||||
@ -49,7 +49,7 @@ func takeJSONNumeric(l lexer) error {
|
|||||||
l.take()
|
l.take()
|
||||||
// Check digit immediately follows period
|
// Check digit immediately follows period
|
||||||
if d := l.peek(); !(d >= '0' && d <= '9') {
|
if d := l.peek(); !(d >= '0' && d <= '9') {
|
||||||
return fmt.Errorf("Expected digit after '.' instead of %#U", d)
|
return fmt.Errorf("expected digit after '.' instead of %#U", d)
|
||||||
}
|
}
|
||||||
takeDigits(l)
|
takeDigits(l)
|
||||||
if err := takeExponent(l); err != nil {
|
if err := takeExponent(l); err != nil {
|
||||||
@ -158,10 +158,11 @@ func abs(x int) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//TODO: Kill the need for this
|
//TODO: Kill the need for this
|
||||||
func getJsonTokenType(val []byte) (int, error) {
|
func getJSONTokenType(val []byte) (int, error) {
|
||||||
if len(val) == 0 {
|
if len(val) == 0 {
|
||||||
return -1, errors.New("No Value")
|
return -1, errors.New("no value")
|
||||||
}
|
}
|
||||||
|
|
||||||
switch val[0] {
|
switch val[0] {
|
||||||
case '{':
|
case '{':
|
||||||
return jsonBraceLeft, nil
|
return jsonBraceLeft, nil
|
||||||
@ -176,6 +177,6 @@ func getJsonTokenType(val []byte) (int, error) {
|
|||||||
case '-', '+', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
case '-', '+', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||||
return jsonNumber, nil
|
return jsonNumber, nil
|
||||||
default:
|
default:
|
||||||
return -1, errors.New("Unrecognized Json Value")
|
return -1, errors.New("unrecognized JSON value")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
46
path.go
46
path.go
@ -36,10 +36,13 @@ type operator struct {
|
|||||||
// nolint:gocognit
|
// nolint:gocognit
|
||||||
func genIndexKey(tr tokenReader) (*operator, error) {
|
func genIndexKey(tr tokenReader) (*operator, error) {
|
||||||
k := &operator{}
|
k := &operator{}
|
||||||
|
|
||||||
var t *Item
|
var t *Item
|
||||||
|
|
||||||
var ok bool
|
var ok bool
|
||||||
|
|
||||||
if t, ok = tr.next(); !ok {
|
if t, ok = tr.next(); !ok {
|
||||||
return nil, errors.New("Expected number, key, or *, but got none")
|
return nil, errors.New("expected number, key, or *, but got none")
|
||||||
}
|
}
|
||||||
|
|
||||||
switch t.typ {
|
switch t.typ {
|
||||||
@ -47,22 +50,23 @@ func genIndexKey(tr tokenReader) (*operator, error) {
|
|||||||
k.typ = opTypeIndexWild
|
k.typ = opTypeIndexWild
|
||||||
k.indexStart = 0
|
k.indexStart = 0
|
||||||
if t, ok = tr.next(); !ok {
|
if t, ok = tr.next(); !ok {
|
||||||
return nil, errors.New("Expected ] after *, but got none")
|
return nil, errors.New("expected ] after *, but got none")
|
||||||
}
|
}
|
||||||
if t.typ != pathBracketRight {
|
if t.typ != pathBracketRight {
|
||||||
return nil, fmt.Errorf("Expected ] after * instead of %q", t.val)
|
return nil, fmt.Errorf("expected ] after * instead of %q", t.val)
|
||||||
}
|
}
|
||||||
case pathIndex:
|
case pathIndex:
|
||||||
v, err := strconv.Atoi(string(t.val))
|
v, err := strconv.Atoi(string(t.val))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Could not parse %q into int64", t.val)
|
return nil, fmt.Errorf("could not parse %q into int64", t.val)
|
||||||
}
|
}
|
||||||
|
|
||||||
k.indexStart = v
|
k.indexStart = v
|
||||||
k.indexEnd = v
|
k.indexEnd = v
|
||||||
k.hasIndexEnd = true
|
k.hasIndexEnd = true
|
||||||
|
|
||||||
if t, ok = tr.next(); !ok {
|
if t, ok = tr.next(); !ok {
|
||||||
return nil, errors.New("Expected number or *, but got none")
|
return nil, errors.New("expected number or *, but got none")
|
||||||
}
|
}
|
||||||
|
|
||||||
switch t.typ {
|
switch t.typ {
|
||||||
@ -77,6 +81,7 @@ func genIndexKey(tr tokenReader) (*operator, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("could not parse %q into int64", t.val)
|
return nil, fmt.Errorf("could not parse %q into int64", t.val)
|
||||||
}
|
}
|
||||||
|
|
||||||
k.indexEnd = v - 1
|
k.indexEnd = v - 1
|
||||||
k.hasIndexEnd = true
|
k.hasIndexEnd = true
|
||||||
|
|
||||||
@ -113,6 +118,7 @@ func genIndexKey(tr tokenReader) (*operator, error) {
|
|||||||
|
|
||||||
func parsePath(pathString string) (*Path, error) {
|
func parsePath(pathString string) (*Path, error) {
|
||||||
lexer := NewSliceLexer([]byte(pathString), PATH)
|
lexer := NewSliceLexer([]byte(pathString), PATH)
|
||||||
|
|
||||||
p, err := tokensToOperators(lexer)
|
p, err := tokensToOperators(lexer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -124,9 +130,11 @@ func parsePath(pathString string) (*Path, error) {
|
|||||||
for _, op := range p.operators {
|
for _, op := range p.operators {
|
||||||
if len(op.whereClauseBytes) > 0 {
|
if len(op.whereClauseBytes) > 0 {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
trimmed := op.whereClauseBytes[1 : len(op.whereClauseBytes)-1]
|
trimmed := op.whereClauseBytes[1 : len(op.whereClauseBytes)-1]
|
||||||
whereLexer := NewSliceLexer(trimmed, EXPRESSION)
|
whereLexer := NewSliceLexer(trimmed, EXPRESSION)
|
||||||
items := readerToArray(whereLexer)
|
items := readerToArray(whereLexer)
|
||||||
|
|
||||||
if errItem, found := findErrors(items); found {
|
if errItem, found := findErrors(items); found {
|
||||||
return nil, errors.New(string(errItem.val))
|
return nil, errors.New(string(errItem.val))
|
||||||
}
|
}
|
||||||
@ -136,6 +144,7 @@ func parsePath(pathString string) (*Path, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
op.dependentPaths = make([]*Path, 0)
|
op.dependentPaths = make([]*Path, 0)
|
||||||
// parse all paths in expression
|
// parse all paths in expression
|
||||||
for _, item := range op.whereClause {
|
for _, item := range op.whereClause {
|
||||||
@ -144,11 +153,13 @@ func parsePath(pathString string) (*Path, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
op.dependentPaths = append(op.dependentPaths, p)
|
op.dependentPaths = append(op.dependentPaths, p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return p, nil
|
return p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,27 +169,28 @@ func tokensToOperators(tr tokenReader) (*Path, error) {
|
|||||||
captureEndValue: false,
|
captureEndValue: false,
|
||||||
operators: make([]*operator, 0),
|
operators: make([]*operator, 0),
|
||||||
}
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
p, ok := tr.next()
|
p, ok := tr.next()
|
||||||
if !ok {
|
if !ok {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
switch p.typ {
|
switch p.typ {
|
||||||
case pathRoot:
|
case pathRoot:
|
||||||
if len(q.operators) != 0 {
|
if len(q.operators) != 0 {
|
||||||
return nil, errors.New("Unexpected root node after start")
|
return nil, errors.New("unexpected root node after start")
|
||||||
}
|
}
|
||||||
continue
|
|
||||||
|
|
||||||
|
continue
|
||||||
case pathCurrent:
|
case pathCurrent:
|
||||||
if len(q.operators) != 0 {
|
if len(q.operators) != 0 {
|
||||||
return nil, errors.New("Unexpected current node after start")
|
return nil, errors.New("unexpected current node after start")
|
||||||
}
|
}
|
||||||
continue
|
|
||||||
|
|
||||||
|
continue
|
||||||
case pathPeriod:
|
case pathPeriod:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
case pathBracketLeft:
|
case pathBracketLeft:
|
||||||
k, err := genIndexKey(tr)
|
k, err := genIndexKey(tr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -190,11 +202,13 @@ func tokensToOperators(tr tokenReader) (*Path, error) {
|
|||||||
keyName := p.val
|
keyName := p.val
|
||||||
|
|
||||||
if len(p.val) == 0 {
|
if len(p.val) == 0 {
|
||||||
return nil, fmt.Errorf("Key length is zero at %d", p.pos)
|
return nil, fmt.Errorf("key length is zero at %d", p.pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.val[0] == '"' && p.val[len(p.val)-1] == '"' {
|
if p.val[0] == '"' && p.val[len(p.val)-1] == '"' {
|
||||||
keyName = p.val[1 : len(p.val)-1]
|
keyName = p.val[1 : len(p.val)-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
q.operators = append(
|
q.operators = append(
|
||||||
q.operators,
|
q.operators,
|
||||||
&operator{
|
&operator{
|
||||||
@ -204,28 +218,28 @@ func tokensToOperators(tr tokenReader) (*Path, error) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
case pathWildcard:
|
case pathWildcard:
|
||||||
q.operators = append(q.operators, &operator{typ: opTypeNameWild})
|
q.operators = append(q.operators, &operator{typ: opTypeNameWild})
|
||||||
|
|
||||||
case pathValue:
|
case pathValue:
|
||||||
q.captureEndValue = true
|
q.captureEndValue = true
|
||||||
|
|
||||||
case pathWhere:
|
case pathWhere:
|
||||||
|
|
||||||
case pathExpression:
|
case pathExpression:
|
||||||
if len(q.operators) == 0 {
|
if len(q.operators) == 0 {
|
||||||
return nil, errors.New("Cannot add where clause on last key")
|
return nil, errors.New("cannot add where clause on last key")
|
||||||
}
|
}
|
||||||
|
|
||||||
last := q.operators[len(q.operators)-1]
|
last := q.operators[len(q.operators)-1]
|
||||||
if last.whereClauseBytes != nil {
|
if last.whereClauseBytes != nil {
|
||||||
return nil, errors.New("Expression on last key already set")
|
return nil, errors.New("expression on last key already set")
|
||||||
}
|
}
|
||||||
last.whereClauseBytes = p.val
|
|
||||||
|
|
||||||
|
last.whereClauseBytes = p.val
|
||||||
case pathError:
|
case pathError:
|
||||||
return q, errors.New(string(p.val))
|
return q, errors.New(string(p.val))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return q, nil
|
return q, nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user