Move to vendor
Signed-off-by: Olivier Gambier <olivier@docker.com>
This commit is contained in:
parent
c8d8e7e357
commit
77e69b9cf3
1268 changed files with 34 additions and 24 deletions
4
vendor/github.com/jmespath/go-jmespath/.gitignore
generated
vendored
Normal file
4
vendor/github.com/jmespath/go-jmespath/.gitignore
generated
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
jpgo
|
||||
jmespath-fuzz.zip
|
||||
cpu.out
|
||||
go-jmespath.test
|
9
vendor/github.com/jmespath/go-jmespath/.travis.yml
generated
vendored
Normal file
9
vendor/github.com/jmespath/go-jmespath/.travis.yml
generated
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
language: go
|
||||
|
||||
sudo: false
|
||||
|
||||
go:
|
||||
- 1.4
|
||||
|
||||
install: go get -v -t ./...
|
||||
script: make test
|
13
vendor/github.com/jmespath/go-jmespath/LICENSE
generated
vendored
Normal file
13
vendor/github.com/jmespath/go-jmespath/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
Copyright 2015 James Saryerwinnie
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
44
vendor/github.com/jmespath/go-jmespath/Makefile
generated
vendored
Normal file
44
vendor/github.com/jmespath/go-jmespath/Makefile
generated
vendored
Normal file
|
@ -0,0 +1,44 @@
|
|||
|
||||
CMD = jpgo
|
||||
|
||||
help:
|
||||
@echo "Please use \`make <target>' where <target> is one of"
|
||||
@echo " test to run all the tests"
|
||||
@echo " build to build the library and jp executable"
|
||||
@echo " generate to run codegen"
|
||||
|
||||
|
||||
generate:
|
||||
go generate ./...
|
||||
|
||||
build:
|
||||
rm -f $(CMD)
|
||||
go build ./...
|
||||
rm -f cmd/$(CMD)/$(CMD) && cd cmd/$(CMD)/ && go build ./...
|
||||
mv cmd/$(CMD)/$(CMD) .
|
||||
|
||||
test:
|
||||
go test -v ./...
|
||||
|
||||
check:
|
||||
go vet ./...
|
||||
@echo "golint ./..."
|
||||
@lint=`golint ./...`; \
|
||||
lint=`echo "$$lint" | grep -v "astnodetype_string.go" | grep -v "toktype_string.go"`; \
|
||||
echo "$$lint"; \
|
||||
if [ "$$lint" != "" ]; then exit 1; fi
|
||||
|
||||
htmlc:
|
||||
go test -coverprofile="/tmp/jpcov" && go tool cover -html="/tmp/jpcov" && unlink /tmp/jpcov
|
||||
|
||||
buildfuzz:
|
||||
go-fuzz-build github.com/jmespath/go-jmespath/fuzz
|
||||
|
||||
fuzz: buildfuzz
|
||||
go-fuzz -bin=./jmespath-fuzz.zip -workdir=fuzz/testdata
|
||||
|
||||
bench:
|
||||
go test -bench . -cpuprofile cpu.out
|
||||
|
||||
pprof-cpu:
|
||||
go tool pprof ./go-jmespath.test ./cpu.out
|
7
vendor/github.com/jmespath/go-jmespath/README.md
generated
vendored
Normal file
7
vendor/github.com/jmespath/go-jmespath/README.md
generated
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
# go-jmespath - A JMESPath implementation in Go
|
||||
|
||||
[](https://travis-ci.org/jmespath/go-jmespath)
|
||||
|
||||
|
||||
|
||||
See http://jmespath.org for more info.
|
49
vendor/github.com/jmespath/go-jmespath/api.go
generated
vendored
Normal file
49
vendor/github.com/jmespath/go-jmespath/api.go
generated
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
package jmespath
|
||||
|
||||
import "strconv"
|
||||
|
||||
// JmesPath is the epresentation of a compiled JMES path query. A JmesPath is
|
||||
// safe for concurrent use by multiple goroutines.
|
||||
type JMESPath struct {
|
||||
ast ASTNode
|
||||
intr *treeInterpreter
|
||||
}
|
||||
|
||||
// Compile parses a JMESPath expression and returns, if successful, a JMESPath
|
||||
// object that can be used to match against data.
|
||||
func Compile(expression string) (*JMESPath, error) {
|
||||
parser := NewParser()
|
||||
ast, err := parser.Parse(expression)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
jmespath := &JMESPath{ast: ast, intr: newInterpreter()}
|
||||
return jmespath, nil
|
||||
}
|
||||
|
||||
// MustCompile is like Compile but panics if the expression cannot be parsed.
|
||||
// It simplifies safe initialization of global variables holding compiled
|
||||
// JMESPaths.
|
||||
func MustCompile(expression string) *JMESPath {
|
||||
jmespath, err := Compile(expression)
|
||||
if err != nil {
|
||||
panic(`jmespath: Compile(` + strconv.Quote(expression) + `): ` + err.Error())
|
||||
}
|
||||
return jmespath
|
||||
}
|
||||
|
||||
// Search evaluates a JMESPath expression against input data and returns the result.
|
||||
func (jp *JMESPath) Search(data interface{}) (interface{}, error) {
|
||||
return jp.intr.Execute(jp.ast, data)
|
||||
}
|
||||
|
||||
// Search evaluates a JMESPath expression against input data and returns the result.
|
||||
func Search(expression string, data interface{}) (interface{}, error) {
|
||||
intr := newInterpreter()
|
||||
parser := NewParser()
|
||||
ast, err := parser.Parse(expression)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return intr.Execute(ast, data)
|
||||
}
|
16
vendor/github.com/jmespath/go-jmespath/astnodetype_string.go
generated
vendored
Normal file
16
vendor/github.com/jmespath/go-jmespath/astnodetype_string.go
generated
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
// generated by stringer -type astNodeType; DO NOT EDIT
|
||||
|
||||
package jmespath
|
||||
|
||||
import "fmt"
|
||||
|
||||
const _astNodeType_name = "ASTEmptyASTComparatorASTCurrentNodeASTExpRefASTFunctionExpressionASTFieldASTFilterProjectionASTFlattenASTIdentityASTIndexASTIndexExpressionASTKeyValPairASTLiteralASTMultiSelectHashASTMultiSelectListASTOrExpressionASTAndExpressionASTNotExpressionASTPipeASTProjectionASTSubexpressionASTSliceASTValueProjection"
|
||||
|
||||
var _astNodeType_index = [...]uint16{0, 8, 21, 35, 44, 65, 73, 92, 102, 113, 121, 139, 152, 162, 180, 198, 213, 229, 245, 252, 265, 281, 289, 307}
|
||||
|
||||
func (i astNodeType) String() string {
|
||||
if i < 0 || i >= astNodeType(len(_astNodeType_index)-1) {
|
||||
return fmt.Sprintf("astNodeType(%d)", i)
|
||||
}
|
||||
return _astNodeType_name[_astNodeType_index[i]:_astNodeType_index[i+1]]
|
||||
}
|
96
vendor/github.com/jmespath/go-jmespath/compliance/basic.json
generated
vendored
Normal file
96
vendor/github.com/jmespath/go-jmespath/compliance/basic.json
generated
vendored
Normal file
|
@ -0,0 +1,96 @@
|
|||
[{
|
||||
"given":
|
||||
{"foo": {"bar": {"baz": "correct"}}},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "foo",
|
||||
"result": {"bar": {"baz": "correct"}}
|
||||
},
|
||||
{
|
||||
"expression": "foo.bar",
|
||||
"result": {"baz": "correct"}
|
||||
},
|
||||
{
|
||||
"expression": "foo.bar.baz",
|
||||
"result": "correct"
|
||||
},
|
||||
{
|
||||
"expression": "foo\n.\nbar\n.baz",
|
||||
"result": "correct"
|
||||
},
|
||||
{
|
||||
"expression": "foo.bar.baz.bad",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "foo.bar.bad",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "foo.bad",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "bad",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "bad.morebad.morebad",
|
||||
"result": null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given":
|
||||
{"foo": {"bar": ["one", "two", "three"]}},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "foo",
|
||||
"result": {"bar": ["one", "two", "three"]}
|
||||
},
|
||||
{
|
||||
"expression": "foo.bar",
|
||||
"result": ["one", "two", "three"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": ["one", "two", "three"],
|
||||
"cases": [
|
||||
{
|
||||
"expression": "one",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "two",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "three",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "one.two",
|
||||
"result": null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given":
|
||||
{"foo": {"1": ["one", "two", "three"], "-1": "bar"}},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "foo.\"1\"",
|
||||
"result": ["one", "two", "three"]
|
||||
},
|
||||
{
|
||||
"expression": "foo.\"1\"[0]",
|
||||
"result": "one"
|
||||
},
|
||||
{
|
||||
"expression": "foo.\"-1\"",
|
||||
"result": "bar"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
257
vendor/github.com/jmespath/go-jmespath/compliance/boolean.json
generated
vendored
Normal file
257
vendor/github.com/jmespath/go-jmespath/compliance/boolean.json
generated
vendored
Normal file
|
@ -0,0 +1,257 @@
|
|||
[
|
||||
{
|
||||
"given": {
|
||||
"outer": {
|
||||
"foo": "foo",
|
||||
"bar": "bar",
|
||||
"baz": "baz"
|
||||
}
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "outer.foo || outer.bar",
|
||||
"result": "foo"
|
||||
},
|
||||
{
|
||||
"expression": "outer.foo||outer.bar",
|
||||
"result": "foo"
|
||||
},
|
||||
{
|
||||
"expression": "outer.bar || outer.baz",
|
||||
"result": "bar"
|
||||
},
|
||||
{
|
||||
"expression": "outer.bar||outer.baz",
|
||||
"result": "bar"
|
||||
},
|
||||
{
|
||||
"expression": "outer.bad || outer.foo",
|
||||
"result": "foo"
|
||||
},
|
||||
{
|
||||
"expression": "outer.bad||outer.foo",
|
||||
"result": "foo"
|
||||
},
|
||||
{
|
||||
"expression": "outer.foo || outer.bad",
|
||||
"result": "foo"
|
||||
},
|
||||
{
|
||||
"expression": "outer.foo||outer.bad",
|
||||
"result": "foo"
|
||||
},
|
||||
{
|
||||
"expression": "outer.bad || outer.alsobad",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "outer.bad||outer.alsobad",
|
||||
"result": null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {
|
||||
"outer": {
|
||||
"foo": "foo",
|
||||
"bool": false,
|
||||
"empty_list": [],
|
||||
"empty_string": ""
|
||||
}
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "outer.empty_string || outer.foo",
|
||||
"result": "foo"
|
||||
},
|
||||
{
|
||||
"expression": "outer.nokey || outer.bool || outer.empty_list || outer.empty_string || outer.foo",
|
||||
"result": "foo"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {
|
||||
"True": true,
|
||||
"False": false,
|
||||
"Number": 5,
|
||||
"EmptyList": [],
|
||||
"Zero": 0
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "True && False",
|
||||
"result": false
|
||||
},
|
||||
{
|
||||
"expression": "False && True",
|
||||
"result": false
|
||||
},
|
||||
{
|
||||
"expression": "True && True",
|
||||
"result": true
|
||||
},
|
||||
{
|
||||
"expression": "False && False",
|
||||
"result": false
|
||||
},
|
||||
{
|
||||
"expression": "True && Number",
|
||||
"result": 5
|
||||
},
|
||||
{
|
||||
"expression": "Number && True",
|
||||
"result": true
|
||||
},
|
||||
{
|
||||
"expression": "Number && False",
|
||||
"result": false
|
||||
},
|
||||
{
|
||||
"expression": "Number && EmptyList",
|
||||
"result": []
|
||||
},
|
||||
{
|
||||
"expression": "Number && True",
|
||||
"result": true
|
||||
},
|
||||
{
|
||||
"expression": "EmptyList && True",
|
||||
"result": []
|
||||
},
|
||||
{
|
||||
"expression": "EmptyList && False",
|
||||
"result": []
|
||||
},
|
||||
{
|
||||
"expression": "True || False",
|
||||
"result": true
|
||||
},
|
||||
{
|
||||
"expression": "True || True",
|
||||
"result": true
|
||||
},
|
||||
{
|
||||
"expression": "False || True",
|
||||
"result": true
|
||||
},
|
||||
{
|
||||
"expression": "False || False",
|
||||
"result": false
|
||||
},
|
||||
{
|
||||
"expression": "Number || EmptyList",
|
||||
"result": 5
|
||||
},
|
||||
{
|
||||
"expression": "Number || True",
|
||||
"result": 5
|
||||
},
|
||||
{
|
||||
"expression": "Number || True && False",
|
||||
"result": 5
|
||||
},
|
||||
{
|
||||
"expression": "(Number || True) && False",
|
||||
"result": false
|
||||
},
|
||||
{
|
||||
"expression": "Number || (True && False)",
|
||||
"result": 5
|
||||
},
|
||||
{
|
||||
"expression": "!True",
|
||||
"result": false
|
||||
},
|
||||
{
|
||||
"expression": "!False",
|
||||
"result": true
|
||||
},
|
||||
{
|
||||
"expression": "!Number",
|
||||
"result": false
|
||||
},
|
||||
{
|
||||
"expression": "!EmptyList",
|
||||
"result": true
|
||||
},
|
||||
{
|
||||
"expression": "True && !False",
|
||||
"result": true
|
||||
},
|
||||
{
|
||||
"expression": "True && !EmptyList",
|
||||
"result": true
|
||||
},
|
||||
{
|
||||
"expression": "!False && !EmptyList",
|
||||
"result": true
|
||||
},
|
||||
{
|
||||
"expression": "!(True && False)",
|
||||
"result": true
|
||||
},
|
||||
{
|
||||
"expression": "!Zero",
|
||||
"result": false
|
||||
},
|
||||
{
|
||||
"expression": "!!Zero",
|
||||
"result": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {
|
||||
"one": 1,
|
||||
"two": 2,
|
||||
"three": 3
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "one < two",
|
||||
"result": true
|
||||
},
|
||||
{
|
||||
"expression": "one <= two",
|
||||
"result": true
|
||||
},
|
||||
{
|
||||
"expression": "one == one",
|
||||
"result": true
|
||||
},
|
||||
{
|
||||
"expression": "one == two",
|
||||
"result": false
|
||||
},
|
||||
{
|
||||
"expression": "one > two",
|
||||
"result": false
|
||||
},
|
||||
{
|
||||
"expression": "one >= two",
|
||||
"result": false
|
||||
},
|
||||
{
|
||||
"expression": "one != two",
|
||||
"result": true
|
||||
},
|
||||
{
|
||||
"expression": "one < two && three > one",
|
||||
"result": true
|
||||
},
|
||||
{
|
||||
"expression": "one < two || three > one",
|
||||
"result": true
|
||||
},
|
||||
{
|
||||
"expression": "one < two || three < one",
|
||||
"result": true
|
||||
},
|
||||
{
|
||||
"expression": "two < one || three < one",
|
||||
"result": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
25
vendor/github.com/jmespath/go-jmespath/compliance/current.json
generated
vendored
Normal file
25
vendor/github.com/jmespath/go-jmespath/compliance/current.json
generated
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
[
|
||||
{
|
||||
"given": {
|
||||
"foo": [{"name": "a"}, {"name": "b"}],
|
||||
"bar": {"baz": "qux"}
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "@",
|
||||
"result": {
|
||||
"foo": [{"name": "a"}, {"name": "b"}],
|
||||
"bar": {"baz": "qux"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"expression": "@.bar",
|
||||
"result": {"baz": "qux"}
|
||||
},
|
||||
{
|
||||
"expression": "@.foo[0]",
|
||||
"result": {"name": "a"}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
46
vendor/github.com/jmespath/go-jmespath/compliance/escape.json
generated
vendored
Normal file
46
vendor/github.com/jmespath/go-jmespath/compliance/escape.json
generated
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
[{
|
||||
"given": {
|
||||
"foo.bar": "dot",
|
||||
"foo bar": "space",
|
||||
"foo\nbar": "newline",
|
||||
"foo\"bar": "doublequote",
|
||||
"c:\\\\windows\\path": "windows",
|
||||
"/unix/path": "unix",
|
||||
"\"\"\"": "threequotes",
|
||||
"bar": {"baz": "qux"}
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "\"foo.bar\"",
|
||||
"result": "dot"
|
||||
},
|
||||
{
|
||||
"expression": "\"foo bar\"",
|
||||
"result": "space"
|
||||
},
|
||||
{
|
||||
"expression": "\"foo\\nbar\"",
|
||||
"result": "newline"
|
||||
},
|
||||
{
|
||||
"expression": "\"foo\\\"bar\"",
|
||||
"result": "doublequote"
|
||||
},
|
||||
{
|
||||
"expression": "\"c:\\\\\\\\windows\\\\path\"",
|
||||
"result": "windows"
|
||||
},
|
||||
{
|
||||
"expression": "\"/unix/path\"",
|
||||
"result": "unix"
|
||||
},
|
||||
{
|
||||
"expression": "\"\\\"\\\"\\\"\"",
|
||||
"result": "threequotes"
|
||||
},
|
||||
{
|
||||
"expression": "\"bar\".\"baz\"",
|
||||
"result": "qux"
|
||||
}
|
||||
]
|
||||
}]
|
468
vendor/github.com/jmespath/go-jmespath/compliance/filters.json
generated
vendored
Normal file
468
vendor/github.com/jmespath/go-jmespath/compliance/filters.json
generated
vendored
Normal file
|
@ -0,0 +1,468 @@
|
|||
[
|
||||
{
|
||||
"given": {"foo": [{"name": "a"}, {"name": "b"}]},
|
||||
"cases": [
|
||||
{
|
||||
"comment": "Matching a literal",
|
||||
"expression": "foo[?name == 'a']",
|
||||
"result": [{"name": "a"}]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {"foo": [0, 1], "bar": [2, 3]},
|
||||
"cases": [
|
||||
{
|
||||
"comment": "Matching a literal",
|
||||
"expression": "*[?[0] == `0`]",
|
||||
"result": [[], []]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {"foo": [{"first": "foo", "last": "bar"},
|
||||
{"first": "foo", "last": "foo"},
|
||||
{"first": "foo", "last": "baz"}]},
|
||||
"cases": [
|
||||
{
|
||||
"comment": "Matching an expression",
|
||||
"expression": "foo[?first == last]",
|
||||
"result": [{"first": "foo", "last": "foo"}]
|
||||
},
|
||||
{
|
||||
"comment": "Verify projection created from filter",
|
||||
"expression": "foo[?first == last].first",
|
||||
"result": ["foo"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {"foo": [{"age": 20},
|
||||
{"age": 25},
|
||||
{"age": 30}]},
|
||||
"cases": [
|
||||
{
|
||||
"comment": "Greater than with a number",
|
||||
"expression": "foo[?age > `25`]",
|
||||
"result": [{"age": 30}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?age >= `25`]",
|
||||
"result": [{"age": 25}, {"age": 30}]
|
||||
},
|
||||
{
|
||||
"comment": "Greater than with a number",
|
||||
"expression": "foo[?age > `30`]",
|
||||
"result": []
|
||||
},
|
||||
{
|
||||
"comment": "Greater than with a number",
|
||||
"expression": "foo[?age < `25`]",
|
||||
"result": [{"age": 20}]
|
||||
},
|
||||
{
|
||||
"comment": "Greater than with a number",
|
||||
"expression": "foo[?age <= `25`]",
|
||||
"result": [{"age": 20}, {"age": 25}]
|
||||
},
|
||||
{
|
||||
"comment": "Greater than with a number",
|
||||
"expression": "foo[?age < `20`]",
|
||||
"result": []
|
||||
},
|
||||
{
|
||||
"expression": "foo[?age == `20`]",
|
||||
"result": [{"age": 20}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?age != `20`]",
|
||||
"result": [{"age": 25}, {"age": 30}]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {"foo": [{"top": {"name": "a"}},
|
||||
{"top": {"name": "b"}}]},
|
||||
"cases": [
|
||||
{
|
||||
"comment": "Filter with subexpression",
|
||||
"expression": "foo[?top.name == 'a']",
|
||||
"result": [{"top": {"name": "a"}}]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {"foo": [{"top": {"first": "foo", "last": "bar"}},
|
||||
{"top": {"first": "foo", "last": "foo"}},
|
||||
{"top": {"first": "foo", "last": "baz"}}]},
|
||||
"cases": [
|
||||
{
|
||||
"comment": "Matching an expression",
|
||||
"expression": "foo[?top.first == top.last]",
|
||||
"result": [{"top": {"first": "foo", "last": "foo"}}]
|
||||
},
|
||||
{
|
||||
"comment": "Matching a JSON array",
|
||||
"expression": "foo[?top == `{\"first\": \"foo\", \"last\": \"bar\"}`]",
|
||||
"result": [{"top": {"first": "foo", "last": "bar"}}]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {"foo": [
|
||||
{"key": true},
|
||||
{"key": false},
|
||||
{"key": 0},
|
||||
{"key": 1},
|
||||
{"key": [0]},
|
||||
{"key": {"bar": [0]}},
|
||||
{"key": null},
|
||||
{"key": [1]},
|
||||
{"key": {"a":2}}
|
||||
]},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "foo[?key == `true`]",
|
||||
"result": [{"key": true}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?key == `false`]",
|
||||
"result": [{"key": false}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?key == `0`]",
|
||||
"result": [{"key": 0}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?key == `1`]",
|
||||
"result": [{"key": 1}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?key == `[0]`]",
|
||||
"result": [{"key": [0]}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?key == `{\"bar\": [0]}`]",
|
||||
"result": [{"key": {"bar": [0]}}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?key == `null`]",
|
||||
"result": [{"key": null}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?key == `[1]`]",
|
||||
"result": [{"key": [1]}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?key == `{\"a\":2}`]",
|
||||
"result": [{"key": {"a":2}}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?`true` == key]",
|
||||
"result": [{"key": true}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?`false` == key]",
|
||||
"result": [{"key": false}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?`0` == key]",
|
||||
"result": [{"key": 0}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?`1` == key]",
|
||||
"result": [{"key": 1}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?`[0]` == key]",
|
||||
"result": [{"key": [0]}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?`{\"bar\": [0]}` == key]",
|
||||
"result": [{"key": {"bar": [0]}}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?`null` == key]",
|
||||
"result": [{"key": null}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?`[1]` == key]",
|
||||
"result": [{"key": [1]}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?`{\"a\":2}` == key]",
|
||||
"result": [{"key": {"a":2}}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?key != `true`]",
|
||||
"result": [{"key": false}, {"key": 0}, {"key": 1}, {"key": [0]},
|
||||
{"key": {"bar": [0]}}, {"key": null}, {"key": [1]}, {"key": {"a":2}}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?key != `false`]",
|
||||
"result": [{"key": true}, {"key": 0}, {"key": 1}, {"key": [0]},
|
||||
{"key": {"bar": [0]}}, {"key": null}, {"key": [1]}, {"key": {"a":2}}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?key != `0`]",
|
||||
"result": [{"key": true}, {"key": false}, {"key": 1}, {"key": [0]},
|
||||
{"key": {"bar": [0]}}, {"key": null}, {"key": [1]}, {"key": {"a":2}}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?key != `1`]",
|
||||
"result": [{"key": true}, {"key": false}, {"key": 0}, {"key": [0]},
|
||||
{"key": {"bar": [0]}}, {"key": null}, {"key": [1]}, {"key": {"a":2}}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?key != `null`]",
|
||||
"result": [{"key": true}, {"key": false}, {"key": 0}, {"key": 1}, {"key": [0]},
|
||||
{"key": {"bar": [0]}}, {"key": [1]}, {"key": {"a":2}}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?key != `[1]`]",
|
||||
"result": [{"key": true}, {"key": false}, {"key": 0}, {"key": 1}, {"key": [0]},
|
||||
{"key": {"bar": [0]}}, {"key": null}, {"key": {"a":2}}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?key != `{\"a\":2}`]",
|
||||
"result": [{"key": true}, {"key": false}, {"key": 0}, {"key": 1}, {"key": [0]},
|
||||
{"key": {"bar": [0]}}, {"key": null}, {"key": [1]}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?`true` != key]",
|
||||
"result": [{"key": false}, {"key": 0}, {"key": 1}, {"key": [0]},
|
||||
{"key": {"bar": [0]}}, {"key": null}, {"key": [1]}, {"key": {"a":2}}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?`false` != key]",
|
||||
"result": [{"key": true}, {"key": 0}, {"key": 1}, {"key": [0]},
|
||||
{"key": {"bar": [0]}}, {"key": null}, {"key": [1]}, {"key": {"a":2}}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?`0` != key]",
|
||||
"result": [{"key": true}, {"key": false}, {"key": 1}, {"key": [0]},
|
||||
{"key": {"bar": [0]}}, {"key": null}, {"key": [1]}, {"key": {"a":2}}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?`1` != key]",
|
||||
"result": [{"key": true}, {"key": false}, {"key": 0}, {"key": [0]},
|
||||
{"key": {"bar": [0]}}, {"key": null}, {"key": [1]}, {"key": {"a":2}}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?`null` != key]",
|
||||
"result": [{"key": true}, {"key": false}, {"key": 0}, {"key": 1}, {"key": [0]},
|
||||
{"key": {"bar": [0]}}, {"key": [1]}, {"key": {"a":2}}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?`[1]` != key]",
|
||||
"result": [{"key": true}, {"key": false}, {"key": 0}, {"key": 1}, {"key": [0]},
|
||||
{"key": {"bar": [0]}}, {"key": null}, {"key": {"a":2}}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?`{\"a\":2}` != key]",
|
||||
"result": [{"key": true}, {"key": false}, {"key": 0}, {"key": 1}, {"key": [0]},
|
||||
{"key": {"bar": [0]}}, {"key": null}, {"key": [1]}]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {"reservations": [
|
||||
{"instances": [
|
||||
{"foo": 1, "bar": 2}, {"foo": 1, "bar": 3},
|
||||
{"foo": 1, "bar": 2}, {"foo": 2, "bar": 1}]}]},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "reservations[].instances[?bar==`1`]",
|
||||
"result": [[{"foo": 2, "bar": 1}]]
|
||||
},
|
||||
{
|
||||
"expression": "reservations[*].instances[?bar==`1`]",
|
||||
"result": [[{"foo": 2, "bar": 1}]]
|
||||
},
|
||||
{
|
||||
"expression": "reservations[].instances[?bar==`1`][]",
|
||||
"result": [{"foo": 2, "bar": 1}]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {
|
||||
"baz": "other",
|
||||
"foo": [
|
||||
{"bar": 1}, {"bar": 2}, {"bar": 3}, {"bar": 4}, {"bar": 1, "baz": 2}
|
||||
]
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "foo[?bar==`1`].bar[0]",
|
||||
"result": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {
|
||||
"foo": [
|
||||
{"a": 1, "b": {"c": "x"}},
|
||||
{"a": 1, "b": {"c": "y"}},
|
||||
{"a": 1, "b": {"c": "z"}},
|
||||
{"a": 2, "b": {"c": "z"}},
|
||||
{"a": 1, "baz": 2}
|
||||
]
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "foo[?a==`1`].b.c",
|
||||
"result": ["x", "y", "z"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {"foo": [{"name": "a"}, {"name": "b"}, {"name": "c"}]},
|
||||
"cases": [
|
||||
{
|
||||
"comment": "Filter with or expression",
|
||||
"expression": "foo[?name == 'a' || name == 'b']",
|
||||
"result": [{"name": "a"}, {"name": "b"}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?name == 'a' || name == 'e']",
|
||||
"result": [{"name": "a"}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?name == 'a' || name == 'b' || name == 'c']",
|
||||
"result": [{"name": "a"}, {"name": "b"}, {"name": "c"}]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {"foo": [{"a": 1, "b": 2}, {"a": 1, "b": 3}]},
|
||||
"cases": [
|
||||
{
|
||||
"comment": "Filter with and expression",
|
||||
"expression": "foo[?a == `1` && b == `2`]",
|
||||
"result": [{"a": 1, "b": 2}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?a == `1` && b == `4`]",
|
||||
"result": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {"foo": [{"a": 1, "b": 2, "c": 3}, {"a": 3, "b": 4}]},
|
||||
"cases": [
|
||||
{
|
||||
"comment": "Filter with Or and And expressions",
|
||||
"expression": "foo[?c == `3` || a == `1` && b == `4`]",
|
||||
"result": [{"a": 1, "b": 2, "c": 3}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?b == `2` || a == `3` && b == `4`]",
|
||||
"result": [{"a": 1, "b": 2, "c": 3}, {"a": 3, "b": 4}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?a == `3` && b == `4` || b == `2`]",
|
||||
"result": [{"a": 1, "b": 2, "c": 3}, {"a": 3, "b": 4}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?(a == `3` && b == `4`) || b == `2`]",
|
||||
"result": [{"a": 1, "b": 2, "c": 3}, {"a": 3, "b": 4}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?((a == `3` && b == `4`)) || b == `2`]",
|
||||
"result": [{"a": 1, "b": 2, "c": 3}, {"a": 3, "b": 4}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?a == `3` && (b == `4` || b == `2`)]",
|
||||
"result": [{"a": 3, "b": 4}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[?a == `3` && ((b == `4` || b == `2`))]",
|
||||
"result": [{"a": 3, "b": 4}]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {"foo": [{"a": 1, "b": 2, "c": 3}, {"a": 3, "b": 4}]},
|
||||
"cases": [
|
||||
{
|
||||
"comment": "Verify precedence of or/and expressions",
|
||||
"expression": "foo[?a == `1` || b ==`2` && c == `5`]",
|
||||
"result": [{"a": 1, "b": 2, "c": 3}]
|
||||
},
|
||||
{
|
||||
"comment": "Parentheses can alter precedence",
|
||||
"expression": "foo[?(a == `1` || b ==`2`) && c == `5`]",
|
||||
"result": []
|
||||
},
|
||||
{
|
||||
"comment": "Not expressions combined with and/or",
|
||||
"expression": "foo[?!(a == `1` || b ==`2`)]",
|
||||
"result": [{"a": 3, "b": 4}]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {
|
||||
"foo": [
|
||||
{"key": true},
|
||||
{"key": false},
|
||||
{"key": []},
|
||||
{"key": {}},
|
||||
{"key": [0]},
|
||||
{"key": {"a": "b"}},
|
||||
{"key": 0},
|
||||
{"key": 1},
|
||||
{"key": null},
|
||||
{"notkey": true}
|
||||
]
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"comment": "Unary filter expression",
|
||||
"expression": "foo[?key]",
|
||||
"result": [
|
||||
{"key": true}, {"key": [0]}, {"key": {"a": "b"}},
|
||||
{"key": 0}, {"key": 1}
|
||||
]
|
||||
},
|
||||
{
|
||||
"comment": "Unary not filter expression",
|
||||
"expression": "foo[?!key]",
|
||||
"result": [
|
||||
{"key": false}, {"key": []}, {"key": {}},
|
||||
{"key": null}, {"notkey": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"comment": "Equality with null RHS",
|
||||
"expression": "foo[?key == `null`]",
|
||||
"result": [
|
||||
{"key": null}, {"notkey": true}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {
|
||||
"foo": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"comment": "Using @ in a filter expression",
|
||||
"expression": "foo[?@ < `5`]",
|
||||
"result": [0, 1, 2, 3, 4]
|
||||
},
|
||||
{
|
||||
"comment": "Using @ in a filter expression",
|
||||
"expression": "foo[?`5` > @]",
|
||||
"result": [0, 1, 2, 3, 4]
|
||||
},
|
||||
{
|
||||
"comment": "Using @ in a filter expression",
|
||||
"expression": "foo[?@ == @]",
|
||||
"result": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
825
vendor/github.com/jmespath/go-jmespath/compliance/functions.json
generated
vendored
Normal file
825
vendor/github.com/jmespath/go-jmespath/compliance/functions.json
generated
vendored
Normal file
|
@ -0,0 +1,825 @@
|
|||
[{
|
||||
"given":
|
||||
{
|
||||
"foo": -1,
|
||||
"zero": 0,
|
||||
"numbers": [-1, 3, 4, 5],
|
||||
"array": [-1, 3, 4, 5, "a", "100"],
|
||||
"strings": ["a", "b", "c"],
|
||||
"decimals": [1.01, 1.2, -1.5],
|
||||
"str": "Str",
|
||||
"false": false,
|
||||
"empty_list": [],
|
||||
"empty_hash": {},
|
||||
"objects": {"foo": "bar", "bar": "baz"},
|
||||
"null_key": null
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "abs(foo)",
|
||||
"result": 1
|
||||
},
|
||||
{
|
||||
"expression": "abs(foo)",
|
||||
"result": 1
|
||||
},
|
||||
{
|
||||
"expression": "abs(str)",
|
||||
"error": "invalid-type"
|
||||
},
|
||||
{
|
||||
"expression": "abs(array[1])",
|
||||
"result": 3
|
||||
},
|
||||
{
|
||||
"expression": "abs(array[1])",
|
||||
"result": 3
|
||||
},
|
||||
{
|
||||
"expression": "abs(`false`)",
|
||||
"error": "invalid-type"
|
||||
},
|
||||
{
|
||||
"expression": "abs(`-24`)",
|
||||
"result": 24
|
||||
},
|
||||
{
|
||||
"expression": "abs(`-24`)",
|
||||
"result": 24
|
||||
},
|
||||
{
|
||||
"expression": "abs(`1`, `2`)",
|
||||
"error": "invalid-arity"
|
||||
},
|
||||
{
|
||||
"expression": "abs()",
|
||||
"error": "invalid-arity"
|
||||
},
|
||||
{
|
||||
"expression": "unknown_function(`1`, `2`)",
|
||||
"error": "unknown-function"
|
||||
},
|
||||
{
|
||||
"expression": "avg(numbers)",
|
||||
"result": 2.75
|
||||
},
|
||||
{
|
||||
"expression": "avg(array)",
|
||||
"error": "invalid-type"
|
||||
},
|
||||
{
|
||||
"expression": "avg('abc')",
|
||||
"error": "invalid-type"
|
||||
},
|
||||
{
|
||||
"expression": "avg(foo)",
|
||||
"error": "invalid-type"
|
||||
},
|
||||
{
|
||||
"expression": "avg(@)",
|
||||
"error": "invalid-type"
|
||||
},
|
||||
{
|
||||
"expression": "avg(strings)",
|
||||
"error": "invalid-type"
|
||||
},
|
||||
{
|
||||
"expression": "ceil(`1.2`)",
|
||||
"result": 2
|
||||
},
|
||||
{
|
||||
"expression": "ceil(decimals[0])",
|
||||
"result": 2
|
||||
},
|
||||
{
|
||||
"expression": "ceil(decimals[1])",
|
||||
"result": 2
|
||||
},
|
||||
{
|
||||
"expression": "ceil(decimals[2])",
|
||||
"result": -1
|
||||
},
|
||||
{
|
||||
"expression": "ceil('string')",
|
||||
"error": "invalid-type"
|
||||
},
|
||||
{
|
||||
"expression": "contains('abc', 'a')",
|
||||
"result": true
|
||||
},
|
||||
{
|
||||
"expression": "contains('abc', 'd')",
|
||||
"result": false
|
||||
},
|
||||
{
|
||||
"expression": "contains(`false`, 'd')",
|
||||
"error": "invalid-type"
|
||||
},
|
||||
{
|
||||
"expression": "contains(strings, 'a')",
|
||||
"result": true
|
||||
},
|
||||
{
|
||||
"expression": "contains(decimals, `1.2`)",
|
||||
"result": true
|
||||
},
|
||||
{
|
||||
"expression": "contains(decimals, `false`)",
|
||||
"result": false
|
||||
},
|
||||
{
|
||||
"expression": "ends_with(str, 'r')",
|
||||
"result": true
|
||||
},
|
||||
{
|
||||
"expression": "ends_with(str, 'tr')",
|
||||
"result": true
|
||||
},
|
||||
{
|
||||
"expression": "ends_with(str, 'Str')",
|
||||
"result": true
|
||||
},
|
||||
{
|
||||
"expression": "ends_with(str, 'SStr')",
|
||||
"result": false
|
||||
},
|
||||
{
|
||||
"expression": "ends_with(str, 'foo')",
|
||||
"result": false
|
||||
},
|
||||
{
|
||||
"expression": "ends_with(str, `0`)",
|
||||
"error": "invalid-type"
|
||||
},
|
||||
{
|
||||
"expression": "floor(`1.2`)",
|
||||
"result": 1
|
||||
},
|
||||
{
|
||||
"expression": "floor('string')",
|
||||
"error": "invalid-type"
|
||||
},
|
||||
{
|
||||
"expression": "floor(decimals[0])",
|
||||
"result": 1
|
||||
},
|
||||
{
|
||||
"expression": "floor(foo)",
|
||||
"result": -1
|
||||
},
|
||||
{
|
||||
"expression": "floor(str)",
|
||||
"error": "invalid-type"
|
||||
},
|
||||
{
|
||||
"expression": "length('abc')",
|
||||
"result": 3
|
||||
},
|
||||
{
|
||||
"expression": "length('✓foo')",
|
||||
"result": 4
|
||||
},
|
||||
{
|
||||
"expression": "length('')",
|
||||
"result": 0
|
||||
},
|
||||
{
|
||||
"expression": "length(@)",
|
||||
"result": 12
|
||||
},
|
||||
{
|
||||
"expression": "length(strings[0])",
|
||||
"result": 1
|
||||
},
|
||||
{
|
||||
"expression": "length(str)",
|
||||
"result": 3
|
||||
},
|
||||
{
|
||||
"expression": "length(array)",
|
||||
"result": 6
|
||||
},
|
||||
{
|
||||
"expression": "length(objects)",
|
||||
"result": 2
|
||||
},
|
||||
{
|
||||
"expression": "length(`false`)",
|
||||
"error": "invalid-type"
|
||||
},
|
||||
{
|
||||
"expression": "length(foo)",
|
||||
"error": "invalid-type"
|
||||
},
|
||||
{
|
||||
"expression": "length(strings[0])",
|
||||
"result": 1
|
||||
},
|
||||
{
|
||||
"expression": "max(numbers)",
|
||||
"result": 5
|
||||
},
|
||||
{
|
||||
"expression": "max(decimals)",
|
||||
"result": 1.2
|
||||
},
|
||||
{
|
||||
"expression": "max(strings)",
|
||||
"result": "c"
|
||||
},
|
||||
{
|
||||
"expression": "max(abc)",
|
||||
"error": "invalid-type"
|
||||
},
|
||||
{
|
||||
"expression": "max(array)",
|
||||
"error": "invalid-type"
|
||||
},
|
||||
{
|
||||
"expression": "max(decimals)",
|
||||
"result": 1.2
|
||||
},
|
||||
{
|
||||
"expression": "max(empty_list)",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "merge(`{}`)",
|
||||
"result": {}
|
||||
},
|
||||
{
|
||||
"expression": "merge(`{}`, `{}`)",
|
||||
"result": {}
|
||||
},
|
||||
{
|
||||
"expression": "merge(`{\"a\": 1}`, `{\"b\": 2}`)",
|
||||
"result": {"a": 1, "b": 2}
|
||||
},
|
||||
{
|
||||
"expression": "merge(`{\"a\": 1}`, `{\"a\": 2}`)",
|
||||
"result": {"a": 2}
|
||||
},
|
||||
{
|
||||
"expression": "merge(`{\"a\": 1, \"b\": 2}`, `{\"a\": 2, \"c\": 3}`, `{\"d\": 4}`)",
|
||||
"result": {"a": 2, "b": 2, "c": 3, "d": 4}
|
||||
},
|
||||
{
|
||||
"expression": "min(numbers)",
|
||||
"result": -1
|
||||
},
|
||||
{
|
||||
"expression": "min(decimals)",
|
||||
"result": -1.5
|
||||
},
|
||||
{
|
||||
"expression": "min(abc)",
|
||||
"error": "invalid-type"
|
||||
},
|
||||
{
|
||||
"expression": "min(array)",
|
||||
"error": "invalid-type"
|
||||
},
|
||||
{
|
||||
"expression": "min(empty_list)",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "min(decimals)",
|
||||
"result": -1.5
|
||||
},
|
||||
{
|
||||
"expression": "min(strings)",
|
||||
"result": "a"
|
||||
},
|
||||
{
|
||||
"expression": "type('abc')",
|
||||
"result": "string"
|
||||
},
|
||||
{
|
||||
"expression": "type(`1.0`)",
|
||||
"result": "number"
|
||||
},
|
||||
{
|
||||
"expression": "type(`2`)",
|
||||
"result": "number"
|
||||
},
|
||||
{
|
||||
"expression": "type(`true`)",
|
||||
"result": "boolean"
|
||||
},
|
||||
{
|
||||
"expression": "type(`false`)",
|
||||
"result": "boolean"
|
||||
},
|
||||
{
|
||||
"expression": "type(`null`)",
|
||||
"result": "null"
|
||||
},
|
||||
{
|
||||
"expression": "type(`[0]`)",
|
||||
"result": "array"
|
||||
},
|
||||
{
|
||||
"expression": "type(`{\"a\": \"b\"}`)",
|
||||
"result": "object"
|
||||
},
|
||||
{
|
||||
"expression": "type(@)",
|
||||
"result": "object"
|
||||
},
|
||||
{
|
||||
"expression": "sort(keys(objects))",
|
||||
"result": ["bar", "foo"]
|
||||
},
|
||||
{
|
||||
"expression": "keys(foo)",
|
||||
"error": "invalid-type"
|
||||
},
|
||||
{
|
||||
"expression": "keys(strings)",
|
||||
"error": "invalid-type"
|
||||
},
|
||||
{
|
||||
"expression": "keys(`false`)",
|
||||
"error": "invalid-type"
|
||||
},
|
||||
{
|
||||
"expression": "sort(values(objects))",
|
||||
"result": ["bar", "baz"]
|
||||
},
|
||||
{
|
||||
"expression": "keys(empty_hash)",
|
||||
"result": []
|
||||
},
|
||||
{
|
||||
"expression": "values(foo)",
|
||||
"error": "invalid-type"
|
||||
},
|
||||
{
|
||||
"expression": "join(', ', strings)",
|
||||
"result": "a, b, c"
|
||||
},
|
||||
{
|
||||
"expression": "join(', ', strings)",
|
||||
"result": "a, b, c"
|
||||
},
|
||||
{
|
||||
"expression": "join(',', `[\"a\", \"b\"]`)",
|
||||
"result": "a,b"
|
||||
},
|
||||
{
|
||||
"expression": "join(',', `[\"a\", 0]`)",
|
||||
"error": "invalid-type"
|
||||
},
|
||||
{
|
||||
"expression": "join(', ', str)",
|
||||
"error": "invalid-type"
|
||||
},
|
||||
{
|
||||
"expression": "join('|', strings)",
|
||||
"result": "a|b|c"
|
||||
},
|
||||
{
|
||||
"expression": "join(`2`, strings)",
|
||||
"error": "invalid-type"
|
||||
},
|
||||
{
|
||||
"expression": "join('|', decimals)",
|
||||
"error": "invalid-type"
|
||||
},
|
||||
{
|
||||
"expression": "join('|', decimals[].to_string(@))",
|
||||
"result": "1.01|1.2|-1.5"
|
||||
},
|
||||
{
|
||||
"expression": "join('|', empty_list)",
|
||||
"result": ""
|
||||
},
|
||||
{
|
||||
"expression": "reverse(numbers)",
|
||||
"result": [5, 4, 3, -1]
|
||||
},
|
||||
{
|
||||
"expression": "reverse(array)",
|
||||
"result": ["100", "a", 5, 4, 3, -1]
|
||||
},
|
||||
{
|
||||
"expression": "reverse(`[]`)",
|
||||
"result": []
|
||||
},
|
||||
{
|
||||
"expression": "reverse('')",
|
||||
"result": ""
|
||||
},
|
||||
{
|
||||
"expression": "reverse('hello world')",
|
||||
"result": "dlrow olleh"
|
||||
},
|
||||
{
|
||||
"expression": "starts_with(str, 'S')",
|
||||
"result": true
|
||||
},
|
||||
{
|
||||
"expression": "starts_with(str, 'St')",
|
||||
"result": true
|
||||
},
|
||||
{
|
||||
"expression": "starts_with(str, 'Str')",
|
||||
"result": true
|
||||
},
|
||||
{
|
||||
"expression": "starts_with(str, 'String')",
|
||||
"result": false
|
||||
},
|
||||
{
|
||||
"expression": "starts_with(str, `0`)",
|
||||
"error": "invalid-type"
|
||||
},
|
||||
{
|
||||
"expression": "sum(numbers)",
|
||||
"result": 11
|
||||
},
|
||||
{
|
||||
"expression": "sum(decimals)",
|
||||
"result": 0.71
|
||||
},
|
||||
{
|
||||
"expression": "sum(array)",
|
||||
"error": "invalid-type"
|
||||
},
|
||||
{
|
||||
"expression": "sum(array[].to_number(@))",
|
||||
"result": 111
|
||||
},
|
||||
{
|
||||
"expression": "sum(`[]`)",
|
||||
"result": 0
|
||||
},
|
||||
{
|
||||
"expression": "to_array('foo')",
|
||||
"result": ["foo"]
|
||||
},
|
||||
{
|
||||
"expression": "to_array(`0`)",
|
||||
"result": [0]
|
||||
},
|
||||
{
|
||||
"expression": "to_array(objects)",
|
||||
"result": [{"foo": "bar", "bar": "baz"}]
|
||||
},
|
||||
{
|
||||
"expression": "to_array(`[1, 2, 3]`)",
|
||||
"result": [1, 2, 3]
|
||||
},
|
||||
{
|
||||
"expression": "to_array(false)",
|
||||
"result": [false]
|
||||
},
|
||||
{
|
||||
"expression": "to_string('foo')",
|
||||
"result": "foo"
|
||||
},
|
||||
{
|
||||
"expression": "to_string(`1.2`)",
|
||||
"result": "1.2"
|
||||
},
|
||||
{
|
||||
"expression": "to_string(`[0, 1]`)",
|
||||
"result": "[0,1]"
|
||||
},
|
||||
{
|
||||
"expression": "to_number('1.0')",
|
||||
"result": 1.0
|
||||
},
|
||||
{
|
||||
"expression": "to_number('1.1')",
|
||||
"result": 1.1
|
||||
},
|
||||
{
|
||||
"expression": "to_number('4')",
|
||||
"result": 4
|
||||
},
|
||||
{
|
||||
"expression": "to_number('notanumber')",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "to_number(`false`)",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "to_number(`null`)",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "to_number(`[0]`)",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "to_number(`{\"foo\": 0}`)",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "\"to_string\"(`1.0`)",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "sort(numbers)",
|
||||
"result": [-1, 3, 4, 5]
|
||||
},
|
||||
{
|
||||
"expression": "sort(strings)",
|
||||
"result": ["a", "b", "c"]
|
||||
},
|
||||
{
|
||||
"expression": "sort(decimals)",
|
||||
"result": [-1.5, 1.01, 1.2]
|
||||
},
|
||||
{
|
||||
"expression": "sort(array)",
|
||||
"error": "invalid-type"
|
||||
},
|
||||
{
|
||||
"expression": "sort(abc)",
|
||||
"error": "invalid-type"
|
||||
},
|
||||
{
|
||||
"expression": "sort(empty_list)",
|
||||
"result": []
|
||||
},
|
||||
{
|
||||
"expression": "sort(@)",
|
||||
"error": "invalid-type"
|
||||
},
|
||||
{
|
||||
"expression": "not_null(unknown_key, str)",
|
||||
"result": "Str"
|
||||
},
|
||||
{
|
||||
"expression": "not_null(unknown_key, foo.bar, empty_list, str)",
|
||||
"result": []
|
||||
},
|
||||
{
|
||||
"expression": "not_null(unknown_key, null_key, empty_list, str)",
|
||||
"result": []
|
||||
},
|
||||
{
|
||||
"expression": "not_null(all, expressions, are_null)",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "not_null()",
|
||||
"error": "invalid-arity"
|
||||
},
|
||||
{
|
||||
"description": "function projection on single arg function",
|
||||
"expression": "numbers[].to_string(@)",
|
||||
"result": ["-1", "3", "4", "5"]
|
||||
},
|
||||
{
|
||||
"description": "function projection on single arg function",
|
||||
"expression": "array[].to_number(@)",
|
||||
"result": [-1, 3, 4, 5, 100]
|
||||
}
|
||||
]
|
||||
}, {
|
||||
"given":
|
||||
{
|
||||
"foo": [
|
||||
{"b": "b", "a": "a"},
|
||||
{"c": "c", "b": "b"},
|
||||
{"d": "d", "c": "c"},
|
||||
{"e": "e", "d": "d"},
|
||||
{"f": "f", "e": "e"}
|
||||
]
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"description": "function projection on variadic function",
|
||||
"expression": "foo[].not_null(f, e, d, c, b, a)",
|
||||
"result": ["b", "c", "d", "e", "f"]
|
||||
}
|
||||
]
|
||||
}, {
|
||||
"given":
|
||||
{
|
||||
"people": [
|
||||
{"age": 20, "age_str": "20", "bool": true, "name": "a", "extra": "foo"},
|
||||
{"age": 40, "age_str": "40", "bool": false, "name": "b", "extra": "bar"},
|
||||
{"age": 30, "age_str": "30", "bool": true, "name": "c"},
|
||||
{"age": 50, "age_str": "50", "bool": false, "name": "d"},
|
||||
{"age": 10, "age_str": "10", "bool": true, "name": 3}
|
||||
]
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"description": "sort by field expression",
|
||||
"expression": "sort_by(people, &age)",
|
||||
"result": [
|
||||
{"age": 10, "age_str": "10", "bool": true, "name": 3},
|
||||
{"age": 20, "age_str": "20", "bool": true, "name": "a", "extra": "foo"},
|
||||
{"age": 30, "age_str": "30", "bool": true, "name": "c"},
|
||||
{"age": 40, "age_str": "40", "bool": false, "name": "b", "extra": "bar"},
|
||||
{"age": 50, "age_str": "50", "bool": false, "name": "d"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"expression": "sort_by(people, &age_str)",
|
||||
"result": [
|
||||
{"age": 10, "age_str": "10", "bool": true, "name": 3},
|
||||
{"age": 20, "age_str": "20", "bool": true, "name": "a", "extra": "foo"},
|
||||
{"age": 30, "age_str": "30", "bool": true, "name": "c"},
|
||||
{"age": 40, "age_str": "40", "bool": false, "name": "b", "extra": "bar"},
|
||||
{"age": 50, "age_str": "50", "bool": false, "name": "d"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "sort by function expression",
|
||||
"expression": "sort_by(people, &to_number(age_str))",
|
||||
"result": [
|
||||
{"age": 10, "age_str": "10", "bool": true, "name": 3},
|
||||
{"age": 20, "age_str": "20", "bool": true, "name": "a", "extra": "foo"},
|
||||
{"age": 30, "age_str": "30", "bool": true, "name": "c"},
|
||||
{"age": 40, "age_str": "40", "bool": false, "name": "b", "extra": "bar"},
|
||||
{"age": 50, "age_str": "50", "bool": false, "name": "d"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "function projection on sort_by function",
|
||||
"expression": "sort_by(people, &age)[].name",
|
||||
"result": [3, "a", "c", "b", "d"]
|
||||
},
|
||||
{
|
||||
"expression": "sort_by(people, &extra)",
|
||||
"error": "invalid-type"
|
||||
},
|
||||
{
|
||||
"expression": "sort_by(people, &bool)",
|
||||
"error": "invalid-type"
|
||||
},
|
||||
{
|
||||
"expression": "sort_by(people, &name)",
|
||||
"error": "invalid-type"
|
||||
},
|
||||
{
|
||||
"expression": "sort_by(people, name)",
|
||||
"error": "invalid-type"
|
||||
},
|
||||
{
|
||||
"expression": "sort_by(people, &age)[].extra",
|
||||
"result": ["foo", "bar"]
|
||||
},
|
||||
{
|
||||
"expression": "sort_by(`[]`, &age)",
|
||||
"result": []
|
||||
},
|
||||
{
|
||||
"expression": "max_by(people, &age)",
|
||||
"result": {"age": 50, "age_str": "50", "bool": false, "name": "d"}
|
||||
},
|
||||
{
|
||||
"expression": "max_by(people, &age_str)",
|
||||
"result": {"age": 50, "age_str": "50", "bool": false, "name": "d"}
|
||||
},
|
||||
{
|
||||
"expression": "max_by(people, &bool)",
|
||||
"error": "invalid-type"
|
||||
},
|
||||
{
|
||||
"expression": "max_by(people, &extra)",
|
||||
"error": "invalid-type"
|
||||
},
|
||||
{
|
||||
"expression": "max_by(people, &to_number(age_str))",
|
||||
"result": {"age": 50, "age_str": "50", "bool": false, "name": "d"}
|
||||
},
|
||||
{
|
||||
"expression": "min_by(people, &age)",
|
||||
"result": {"age": 10, "age_str": "10", "bool": true, "name": 3}
|
||||
},
|
||||
{
|
||||
"expression": "min_by(people, &age_str)",
|
||||
"result": {"age": 10, "age_str": "10", "bool": true, "name": 3}
|
||||
},
|
||||
{
|
||||
"expression": "min_by(people, &bool)",
|
||||
"error": "invalid-type"
|
||||
},
|
||||
{
|
||||
"expression": "min_by(people, &extra)",
|
||||
"error": "invalid-type"
|
||||
},
|
||||
{
|
||||
"expression": "min_by(people, &to_number(age_str))",
|
||||
"result": {"age": 10, "age_str": "10", "bool": true, "name": 3}
|
||||
}
|
||||
]
|
||||
}, {
|
||||
"given":
|
||||
{
|
||||
"people": [
|
||||
{"age": 10, "order": "1"},
|
||||
{"age": 10, "order": "2"},
|
||||
{"age": 10, "order": "3"},
|
||||
{"age": 10, "order": "4"},
|
||||
{"age": 10, "order": "5"},
|
||||
{"age": 10, "order": "6"},
|
||||
{"age": 10, "order": "7"},
|
||||
{"age": 10, "order": "8"},
|
||||
{"age": 10, "order": "9"},
|
||||
{"age": 10, "order": "10"},
|
||||
{"age": 10, "order": "11"}
|
||||
]
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"description": "stable sort order",
|
||||
"expression": "sort_by(people, &age)",
|
||||
"result": [
|
||||
{"age": 10, "order": "1"},
|
||||
{"age": 10, "order": "2"},
|
||||
{"age": 10, "order": "3"},
|
||||
{"age": 10, "order": "4"},
|
||||
{"age": 10, "order": "5"},
|
||||
{"age": 10, "order": "6"},
|
||||
{"age": 10, "order": "7"},
|
||||
{"age": 10, "order": "8"},
|
||||
{"age": 10, "order": "9"},
|
||||
{"age": 10, "order": "10"},
|
||||
{"age": 10, "order": "11"}
|
||||
]
|
||||
}
|
||||
]
|
||||
}, {
|
||||
"given":
|
||||
{
|
||||
"people": [
|
||||
{"a": 10, "b": 1, "c": "z"},
|
||||
{"a": 10, "b": 2, "c": null},
|
||||
{"a": 10, "b": 3},
|
||||
{"a": 10, "b": 4, "c": "z"},
|
||||
{"a": 10, "b": 5, "c": null},
|
||||
{"a": 10, "b": 6},
|
||||
{"a": 10, "b": 7, "c": "z"},
|
||||
{"a": 10, "b": 8, "c": null},
|
||||
{"a": 10, "b": 9}
|
||||
],
|
||||
"empty": []
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "map(&a, people)",
|
||||
"result": [10, 10, 10, 10, 10, 10, 10, 10, 10]
|
||||
},
|
||||
{
|
||||
"expression": "map(&c, people)",
|
||||
"result": ["z", null, null, "z", null, null, "z", null, null]
|
||||
},
|
||||
{
|
||||
"expression": "map(&a, badkey)",
|
||||
"error": "invalid-type"
|
||||
},
|
||||
{
|
||||
"expression": "map(&foo, empty)",
|
||||
"result": []
|
||||
}
|
||||
]
|
||||
}, {
|
||||
"given": {
|
||||
"array": [
|
||||
{
|
||||
"foo": {"bar": "yes1"}
|
||||
},
|
||||
{
|
||||
"foo": {"bar": "yes2"}
|
||||
},
|
||||
{
|
||||
"foo1": {"bar": "no"}
|
||||
}
|
||||
]},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "map(&foo.bar, array)",
|
||||
"result": ["yes1", "yes2", null]
|
||||
},
|
||||
{
|
||||
"expression": "map(&foo1.bar, array)",
|
||||
"result": [null, null, "no"]
|
||||
},
|
||||
{
|
||||
"expression": "map(&foo.bar.baz, array)",
|
||||
"result": [null, null, null]
|
||||
}
|
||||
]
|
||||
}, {
|
||||
"given": {
|
||||
"array": [[1, 2, 3, [4]], [5, 6, 7, [8, 9]]]
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "map(&[], array)",
|
||||
"result": [[1, 2, 3, 4], [5, 6, 7, 8, 9]]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
1377
vendor/github.com/jmespath/go-jmespath/compliance/identifiers.json
generated
vendored
Normal file
1377
vendor/github.com/jmespath/go-jmespath/compliance/identifiers.json
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
346
vendor/github.com/jmespath/go-jmespath/compliance/indices.json
generated
vendored
Normal file
346
vendor/github.com/jmespath/go-jmespath/compliance/indices.json
generated
vendored
Normal file
|
@ -0,0 +1,346 @@
|
|||
[{
|
||||
"given":
|
||||
{"foo": {"bar": ["zero", "one", "two"]}},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "foo.bar[0]",
|
||||
"result": "zero"
|
||||
},
|
||||
{
|
||||
"expression": "foo.bar[1]",
|
||||
"result": "one"
|
||||
},
|
||||
{
|
||||
"expression": "foo.bar[2]",
|
||||
"result": "two"
|
||||
},
|
||||
{
|
||||
"expression": "foo.bar[3]",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "foo.bar[-1]",
|
||||
"result": "two"
|
||||
},
|
||||
{
|
||||
"expression": "foo.bar[-2]",
|
||||
"result": "one"
|
||||
},
|
||||
{
|
||||
"expression": "foo.bar[-3]",
|
||||
"result": "zero"
|
||||
},
|
||||
{
|
||||
"expression": "foo.bar[-4]",
|
||||
"result": null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given":
|
||||
{"foo": [{"bar": "one"}, {"bar": "two"}, {"bar": "three"}, {"notbar": "four"}]},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "foo.bar",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "foo[0].bar",
|
||||
"result": "one"
|
||||
},
|
||||
{
|
||||
"expression": "foo[1].bar",
|
||||
"result": "two"
|
||||
},
|
||||
{
|
||||
"expression": "foo[2].bar",
|
||||
"result": "three"
|
||||
},
|
||||
{
|
||||
"expression": "foo[3].notbar",
|
||||
"result": "four"
|
||||
},
|
||||
{
|
||||
"expression": "foo[3].bar",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "foo[0]",
|
||||
"result": {"bar": "one"}
|
||||
},
|
||||
{
|
||||
"expression": "foo[1]",
|
||||
"result": {"bar": "two"}
|
||||
},
|
||||
{
|
||||
"expression": "foo[2]",
|
||||
"result": {"bar": "three"}
|
||||
},
|
||||
{
|
||||
"expression": "foo[3]",
|
||||
"result": {"notbar": "four"}
|
||||
},
|
||||
{
|
||||
"expression": "foo[4]",
|
||||
"result": null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": [
|
||||
"one", "two", "three"
|
||||
],
|
||||
"cases": [
|
||||
{
|
||||
"expression": "[0]",
|
||||
"result": "one"
|
||||
},
|
||||
{
|
||||
"expression": "[1]",
|
||||
"result": "two"
|
||||
},
|
||||
{
|
||||
"expression": "[2]",
|
||||
"result": "three"
|
||||
},
|
||||
{
|
||||
"expression": "[-1]",
|
||||
"result": "three"
|
||||
},
|
||||
{
|
||||
"expression": "[-2]",
|
||||
"result": "two"
|
||||
},
|
||||
{
|
||||
"expression": "[-3]",
|
||||
"result": "one"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {"reservations": [
|
||||
{"instances": [{"foo": 1}, {"foo": 2}]}
|
||||
]},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "reservations[].instances[].foo",
|
||||
"result": [1, 2]
|
||||
},
|
||||
{
|
||||
"expression": "reservations[].instances[].bar",
|
||||
"result": []
|
||||
},
|
||||
{
|
||||
"expression": "reservations[].notinstances[].foo",
|
||||
"result": []
|
||||
},
|
||||
{
|
||||
"expression": "reservations[].notinstances[].foo",
|
||||
"result": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {"reservations": [{
|
||||
"instances": [
|
||||
{"foo": [{"bar": 1}, {"bar": 2}, {"notbar": 3}, {"bar": 4}]},
|
||||
{"foo": [{"bar": 5}, {"bar": 6}, {"notbar": [7]}, {"bar": 8}]},
|
||||
{"foo": "bar"},
|
||||
{"notfoo": [{"bar": 20}, {"bar": 21}, {"notbar": [7]}, {"bar": 22}]},
|
||||
{"bar": [{"baz": [1]}, {"baz": [2]}, {"baz": [3]}, {"baz": [4]}]},
|
||||
{"baz": [{"baz": [1, 2]}, {"baz": []}, {"baz": []}, {"baz": [3, 4]}]},
|
||||
{"qux": [{"baz": []}, {"baz": [1, 2, 3]}, {"baz": [4]}, {"baz": []}]}
|
||||
],
|
||||
"otherkey": {"foo": [{"bar": 1}, {"bar": 2}, {"notbar": 3}, {"bar": 4}]}
|
||||
}, {
|
||||
"instances": [
|
||||
{"a": [{"bar": 1}, {"bar": 2}, {"notbar": 3}, {"bar": 4}]},
|
||||
{"b": [{"bar": 5}, {"bar": 6}, {"notbar": [7]}, {"bar": 8}]},
|
||||
{"c": "bar"},
|
||||
{"notfoo": [{"bar": 23}, {"bar": 24}, {"notbar": [7]}, {"bar": 25}]},
|
||||
{"qux": [{"baz": []}, {"baz": [1, 2, 3]}, {"baz": [4]}, {"baz": []}]}
|
||||
],
|
||||
"otherkey": {"foo": [{"bar": 1}, {"bar": 2}, {"notbar": 3}, {"bar": 4}]}
|
||||
}
|
||||
]},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "reservations[].instances[].foo[].bar",
|
||||
"result": [1, 2, 4, 5, 6, 8]
|
||||
},
|
||||
{
|
||||
"expression": "reservations[].instances[].foo[].baz",
|
||||
"result": []
|
||||
},
|
||||
{
|
||||
"expression": "reservations[].instances[].notfoo[].bar",
|
||||
"result": [20, 21, 22, 23, 24, 25]
|
||||
},
|
||||
{
|
||||
"expression": "reservations[].instances[].notfoo[].notbar",
|
||||
"result": [[7], [7]]
|
||||
},
|
||||
{
|
||||
"expression": "reservations[].notinstances[].foo",
|
||||
"result": []
|
||||
},
|
||||
{
|
||||
"expression": "reservations[].instances[].foo[].notbar",
|
||||
"result": [3, [7]]
|
||||
},
|
||||
{
|
||||
"expression": "reservations[].instances[].bar[].baz",
|
||||
"result": [[1], [2], [3], [4]]
|
||||
},
|
||||
{
|
||||
"expression": "reservations[].instances[].baz[].baz",
|
||||
"result": [[1, 2], [], [], [3, 4]]
|
||||
},
|
||||
{
|
||||
"expression": "reservations[].instances[].qux[].baz",
|
||||
"result": [[], [1, 2, 3], [4], [], [], [1, 2, 3], [4], []]
|
||||
},
|
||||
{
|
||||
"expression": "reservations[].instances[].qux[].baz[]",
|
||||
"result": [1, 2, 3, 4, 1, 2, 3, 4]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {
|
||||
"foo": [
|
||||
[["one", "two"], ["three", "four"]],
|
||||
[["five", "six"], ["seven", "eight"]],
|
||||
[["nine"], ["ten"]]
|
||||
]
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "foo[]",
|
||||
"result": [["one", "two"], ["three", "four"], ["five", "six"],
|
||||
["seven", "eight"], ["nine"], ["ten"]]
|
||||
},
|
||||
{
|
||||
"expression": "foo[][0]",
|
||||
"result": ["one", "three", "five", "seven", "nine", "ten"]
|
||||
},
|
||||
{
|
||||
"expression": "foo[][1]",
|
||||
"result": ["two", "four", "six", "eight"]
|
||||
},
|
||||
{
|
||||
"expression": "foo[][0][0]",
|
||||
"result": []
|
||||
},
|
||||
{
|
||||
"expression": "foo[][2][2]",
|
||||
"result": []
|
||||
},
|
||||
{
|
||||
"expression": "foo[][0][0][100]",
|
||||
"result": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {
|
||||
"foo": [{
|
||||
"bar": [
|
||||
{
|
||||
"qux": 2,
|
||||
"baz": 1
|
||||
},
|
||||
{
|
||||
"qux": 4,
|
||||
"baz": 3
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"bar": [
|
||||
{
|
||||
"qux": 6,
|
||||
"baz": 5
|
||||
},
|
||||
{
|
||||
"qux": 8,
|
||||
"baz": 7
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "foo",
|
||||
"result": [{"bar": [{"qux": 2, "baz": 1}, {"qux": 4, "baz": 3}]},
|
||||
{"bar": [{"qux": 6, "baz": 5}, {"qux": 8, "baz": 7}]}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[]",
|
||||
"result": [{"bar": [{"qux": 2, "baz": 1}, {"qux": 4, "baz": 3}]},
|
||||
{"bar": [{"qux": 6, "baz": 5}, {"qux": 8, "baz": 7}]}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[].bar",
|
||||
"result": [[{"qux": 2, "baz": 1}, {"qux": 4, "baz": 3}],
|
||||
[{"qux": 6, "baz": 5}, {"qux": 8, "baz": 7}]]
|
||||
},
|
||||
{
|
||||
"expression": "foo[].bar[]",
|
||||
"result": [{"qux": 2, "baz": 1}, {"qux": 4, "baz": 3},
|
||||
{"qux": 6, "baz": 5}, {"qux": 8, "baz": 7}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[].bar[].baz",
|
||||
"result": [1, 3, 5, 7]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {
|
||||
"string": "string",
|
||||
"hash": {"foo": "bar", "bar": "baz"},
|
||||
"number": 23,
|
||||
"nullvalue": null
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "string[]",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "hash[]",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "number[]",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "nullvalue[]",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "string[].foo",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "hash[].foo",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "number[].foo",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "nullvalue[].foo",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "nullvalue[].foo[].bar",
|
||||
"result": null
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
185
vendor/github.com/jmespath/go-jmespath/compliance/literal.json
generated
vendored
Normal file
185
vendor/github.com/jmespath/go-jmespath/compliance/literal.json
generated
vendored
Normal file
|
@ -0,0 +1,185 @@
|
|||
[
|
||||
{
|
||||
"given": {
|
||||
"foo": [{"name": "a"}, {"name": "b"}],
|
||||
"bar": {"baz": "qux"}
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "`\"foo\"`",
|
||||
"result": "foo"
|
||||
},
|
||||
{
|
||||
"comment": "Interpret escaped unicode.",
|
||||
"expression": "`\"\\u03a6\"`",
|
||||
"result": "Φ"
|
||||
},
|
||||
{
|
||||
"expression": "`\"✓\"`",
|
||||
"result": "✓"
|
||||
},
|
||||
{
|
||||
"expression": "`[1, 2, 3]`",
|
||||
"result": [1, 2, 3]
|
||||
},
|
||||
{
|
||||
"expression": "`{\"a\": \"b\"}`",
|
||||
"result": {"a": "b"}
|
||||
},
|
||||
{
|
||||
"expression": "`true`",
|
||||
"result": true
|
||||
},
|
||||
{
|
||||
"expression": "`false`",
|
||||
"result": false
|
||||
},
|
||||
{
|
||||
"expression": "`null`",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "`0`",
|
||||
"result": 0
|
||||
},
|
||||
{
|
||||
"expression": "`1`",
|
||||
"result": 1
|
||||
},
|
||||
{
|
||||
"expression": "`2`",
|
||||
"result": 2
|
||||
},
|
||||
{
|
||||
"expression": "`3`",
|
||||
"result": 3
|
||||
},
|
||||
{
|
||||
"expression": "`4`",
|
||||
"result": 4
|
||||
},
|
||||
{
|
||||
"expression": "`5`",
|
||||
"result": 5
|
||||
},
|
||||
{
|
||||
"expression": "`6`",
|
||||
"result": 6
|
||||
},
|
||||
{
|
||||
"expression": "`7`",
|
||||
"result": 7
|
||||
},
|
||||
{
|
||||
"expression": "`8`",
|
||||
"result": 8
|
||||
},
|
||||
{
|
||||
"expression": "`9`",
|
||||
"result": 9
|
||||
},
|
||||
{
|
||||
"comment": "Escaping a backtick in quotes",
|
||||
"expression": "`\"foo\\`bar\"`",
|
||||
"result": "foo`bar"
|
||||
},
|
||||
{
|
||||
"comment": "Double quote in literal",
|
||||
"expression": "`\"foo\\\"bar\"`",
|
||||
"result": "foo\"bar"
|
||||
},
|
||||
{
|
||||
"expression": "`\"1\\`\"`",
|
||||
"result": "1`"
|
||||
},
|
||||
{
|
||||
"comment": "Multiple literal expressions with escapes",
|
||||
"expression": "`\"\\\\\"`.{a:`\"b\"`}",
|
||||
"result": {"a": "b"}
|
||||
},
|
||||
{
|
||||
"comment": "literal . identifier",
|
||||
"expression": "`{\"a\": \"b\"}`.a",
|
||||
"result": "b"
|
||||
},
|
||||
{
|
||||
"comment": "literal . identifier . identifier",
|
||||
"expression": "`{\"a\": {\"b\": \"c\"}}`.a.b",
|
||||
"result": "c"
|
||||
},
|
||||
{
|
||||
"comment": "literal . identifier bracket-expr",
|
||||
"expression": "`[0, 1, 2]`[1]",
|
||||
"result": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"comment": "Literals",
|
||||
"given": {"type": "object"},
|
||||
"cases": [
|
||||
{
|
||||
"comment": "Literal with leading whitespace",
|
||||
"expression": "` {\"foo\": true}`",
|
||||
"result": {"foo": true}
|
||||
},
|
||||
{
|
||||
"comment": "Literal with trailing whitespace",
|
||||
"expression": "`{\"foo\": true} `",
|
||||
"result": {"foo": true}
|
||||
},
|
||||
{
|
||||
"comment": "Literal on RHS of subexpr not allowed",
|
||||
"expression": "foo.`\"bar\"`",
|
||||
"error": "syntax"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"comment": "Raw String Literals",
|
||||
"given": {},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "'foo'",
|
||||
"result": "foo"
|
||||
},
|
||||
{
|
||||
"expression": "' foo '",
|
||||
"result": " foo "
|
||||
},
|
||||
{
|
||||
"expression": "'0'",
|
||||
"result": "0"
|
||||
},
|
||||
{
|
||||
"expression": "'newline\n'",
|
||||
"result": "newline\n"
|
||||
},
|
||||
{
|
||||
"expression": "'\n'",
|
||||
"result": "\n"
|
||||
},
|
||||
{
|
||||
"expression": "'✓'",
|
||||
"result": "✓"
|
||||
},
|
||||
{
|
||||
"expression": "'𝄞'",
|
||||
"result": "𝄞"
|
||||
},
|
||||
{
|
||||
"expression": "' [foo] '",
|
||||
"result": " [foo] "
|
||||
},
|
||||
{
|
||||
"expression": "'[foo]'",
|
||||
"result": "[foo]"
|
||||
},
|
||||
{
|
||||
"comment": "Do not interpret escaped unicode.",
|
||||
"expression": "'\\u03a6'",
|
||||
"result": "\\u03a6"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
393
vendor/github.com/jmespath/go-jmespath/compliance/multiselect.json
generated
vendored
Normal file
393
vendor/github.com/jmespath/go-jmespath/compliance/multiselect.json
generated
vendored
Normal file
|
@ -0,0 +1,393 @@
|
|||
[{
|
||||
"given": {
|
||||
"foo": {
|
||||
"bar": "bar",
|
||||
"baz": "baz",
|
||||
"qux": "qux",
|
||||
"nested": {
|
||||
"one": {
|
||||
"a": "first",
|
||||
"b": "second",
|
||||
"c": "third"
|
||||
},
|
||||
"two": {
|
||||
"a": "first",
|
||||
"b": "second",
|
||||
"c": "third"
|
||||
},
|
||||
"three": {
|
||||
"a": "first",
|
||||
"b": "second",
|
||||
"c": {"inner": "third"}
|
||||
}
|
||||
}
|
||||
},
|
||||
"bar": 1,
|
||||
"baz": 2,
|
||||
"qux\"": 3
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "foo.{bar: bar}",
|
||||
"result": {"bar": "bar"}
|
||||
},
|
||||
{
|
||||
"expression": "foo.{\"bar\": bar}",
|
||||
"result": {"bar": "bar"}
|
||||
},
|
||||
{
|
||||
"expression": "foo.{\"foo.bar\": bar}",
|
||||
"result": {"foo.bar": "bar"}
|
||||
},
|
||||
{
|
||||
"expression": "foo.{bar: bar, baz: baz}",
|
||||
"result": {"bar": "bar", "baz": "baz"}
|
||||
},
|
||||
{
|
||||
"expression": "foo.{\"bar\": bar, \"baz\": baz}",
|
||||
"result": {"bar": "bar", "baz": "baz"}
|
||||
},
|
||||
{
|
||||
"expression": "{\"baz\": baz, \"qux\\\"\": \"qux\\\"\"}",
|
||||
"result": {"baz": 2, "qux\"": 3}
|
||||
},
|
||||
{
|
||||
"expression": "foo.{bar:bar,baz:baz}",
|
||||
"result": {"bar": "bar", "baz": "baz"}
|
||||
},
|
||||
{
|
||||
"expression": "foo.{bar: bar,qux: qux}",
|
||||
"result": {"bar": "bar", "qux": "qux"}
|
||||
},
|
||||
{
|
||||
"expression": "foo.{bar: bar, noexist: noexist}",
|
||||
"result": {"bar": "bar", "noexist": null}
|
||||
},
|
||||
{
|
||||
"expression": "foo.{noexist: noexist, alsonoexist: alsonoexist}",
|
||||
"result": {"noexist": null, "alsonoexist": null}
|
||||
},
|
||||
{
|
||||
"expression": "foo.badkey.{nokey: nokey, alsonokey: alsonokey}",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "foo.nested.*.{a: a,b: b}",
|
||||
"result": [{"a": "first", "b": "second"},
|
||||
{"a": "first", "b": "second"},
|
||||
{"a": "first", "b": "second"}]
|
||||
},
|
||||
{
|
||||
"expression": "foo.nested.three.{a: a, cinner: c.inner}",
|
||||
"result": {"a": "first", "cinner": "third"}
|
||||
},
|
||||
{
|
||||
"expression": "foo.nested.three.{a: a, c: c.inner.bad.key}",
|
||||
"result": {"a": "first", "c": null}
|
||||
},
|
||||
{
|
||||
"expression": "foo.{a: nested.one.a, b: nested.two.b}",
|
||||
"result": {"a": "first", "b": "second"}
|
||||
},
|
||||
{
|
||||
"expression": "{bar: bar, baz: baz}",
|
||||
"result": {"bar": 1, "baz": 2}
|
||||
},
|
||||
{
|
||||
"expression": "{bar: bar}",
|
||||
"result": {"bar": 1}
|
||||
},
|
||||
{
|
||||
"expression": "{otherkey: bar}",
|
||||
"result": {"otherkey": 1}
|
||||
},
|
||||
{
|
||||
"expression": "{no: no, exist: exist}",
|
||||
"result": {"no": null, "exist": null}
|
||||
},
|
||||
{
|
||||
"expression": "foo.[bar]",
|
||||
"result": ["bar"]
|
||||
},
|
||||
{
|
||||
"expression": "foo.[bar,baz]",
|
||||
"result": ["bar", "baz"]
|
||||
},
|
||||
{
|
||||
"expression": "foo.[bar,qux]",
|
||||
"result": ["bar", "qux"]
|
||||
},
|
||||
{
|
||||
"expression": "foo.[bar,noexist]",
|
||||
"result": ["bar", null]
|
||||
},
|
||||
{
|
||||
"expression": "foo.[noexist,alsonoexist]",
|
||||
"result": [null, null]
|
||||
}
|
||||
]
|
||||
}, {
|
||||
"given": {
|
||||
"foo": {"bar": 1, "baz": [2, 3, 4]}
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "foo.{bar:bar,baz:baz}",
|
||||
"result": {"bar": 1, "baz": [2, 3, 4]}
|
||||
},
|
||||
{
|
||||
"expression": "foo.[bar,baz[0]]",
|
||||
"result": [1, 2]
|
||||
},
|
||||
{
|
||||
"expression": "foo.[bar,baz[1]]",
|
||||
"result": [1, 3]
|
||||
},
|
||||
{
|
||||
"expression": "foo.[bar,baz[2]]",
|
||||
"result": [1, 4]
|
||||
},
|
||||
{
|
||||
"expression": "foo.[bar,baz[3]]",
|
||||
"result": [1, null]
|
||||
},
|
||||
{
|
||||
"expression": "foo.[bar[0],baz[3]]",
|
||||
"result": [null, null]
|
||||
}
|
||||
]
|
||||
}, {
|
||||
"given": {
|
||||
"foo": {"bar": 1, "baz": 2}
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "foo.{bar: bar, baz: baz}",
|
||||
"result": {"bar": 1, "baz": 2}
|
||||
},
|
||||
{
|
||||
"expression": "foo.[bar,baz]",
|
||||
"result": [1, 2]
|
||||
}
|
||||
]
|
||||
}, {
|
||||
"given": {
|
||||
"foo": {
|
||||
"bar": {"baz": [{"common": "first", "one": 1},
|
||||
{"common": "second", "two": 2}]},
|
||||
"ignoreme": 1,
|
||||
"includeme": true
|
||||
}
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "foo.{bar: bar.baz[1],includeme: includeme}",
|
||||
"result": {"bar": {"common": "second", "two": 2}, "includeme": true}
|
||||
},
|
||||
{
|
||||
"expression": "foo.{\"bar.baz.two\": bar.baz[1].two, includeme: includeme}",
|
||||
"result": {"bar.baz.two": 2, "includeme": true}
|
||||
},
|
||||
{
|
||||
"expression": "foo.[includeme, bar.baz[*].common]",
|
||||
"result": [true, ["first", "second"]]
|
||||
},
|
||||
{
|
||||
"expression": "foo.[includeme, bar.baz[*].none]",
|
||||
"result": [true, []]
|
||||
},
|
||||
{
|
||||
"expression": "foo.[includeme, bar.baz[].common]",
|
||||
"result": [true, ["first", "second"]]
|
||||
}
|
||||
]
|
||||
}, {
|
||||
"given": {
|
||||
"reservations": [{
|
||||
"instances": [
|
||||
{"id": "id1",
|
||||
"name": "first"},
|
||||
{"id": "id2",
|
||||
"name": "second"}
|
||||
]}, {
|
||||
"instances": [
|
||||
{"id": "id3",
|
||||
"name": "third"},
|
||||
{"id": "id4",
|
||||
"name": "fourth"}
|
||||
]}
|
||||
]},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "reservations[*].instances[*].{id: id, name: name}",
|
||||
"result": [[{"id": "id1", "name": "first"}, {"id": "id2", "name": "second"}],
|
||||
[{"id": "id3", "name": "third"}, {"id": "id4", "name": "fourth"}]]
|
||||
},
|
||||
{
|
||||
"expression": "reservations[].instances[].{id: id, name: name}",
|
||||
"result": [{"id": "id1", "name": "first"},
|
||||
{"id": "id2", "name": "second"},
|
||||
{"id": "id3", "name": "third"},
|
||||
{"id": "id4", "name": "fourth"}]
|
||||
},
|
||||
{
|
||||
"expression": "reservations[].instances[].[id, name]",
|
||||
"result": [["id1", "first"],
|
||||
["id2", "second"],
|
||||
["id3", "third"],
|
||||
["id4", "fourth"]]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {
|
||||
"foo": [{
|
||||
"bar": [
|
||||
{
|
||||
"qux": 2,
|
||||
"baz": 1
|
||||
},
|
||||
{
|
||||
"qux": 4,
|
||||
"baz": 3
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"bar": [
|
||||
{
|
||||
"qux": 6,
|
||||
"baz": 5
|
||||
},
|
||||
{
|
||||
"qux": 8,
|
||||
"baz": 7
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "foo",
|
||||
"result": [{"bar": [{"qux": 2, "baz": 1}, {"qux": 4, "baz": 3}]},
|
||||
{"bar": [{"qux": 6, "baz": 5}, {"qux": 8, "baz": 7}]}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[]",
|
||||
"result": [{"bar": [{"qux": 2, "baz": 1}, {"qux": 4, "baz": 3}]},
|
||||
{"bar": [{"qux": 6, "baz": 5}, {"qux": 8, "baz": 7}]}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[].bar",
|
||||
"result": [[{"qux": 2, "baz": 1}, {"qux": 4, "baz": 3}],
|
||||
[{"qux": 6, "baz": 5}, {"qux": 8, "baz": 7}]]
|
||||
},
|
||||
{
|
||||
"expression": "foo[].bar[]",
|
||||
"result": [{"qux": 2, "baz": 1}, {"qux": 4, "baz": 3},
|
||||
{"qux": 6, "baz": 5}, {"qux": 8, "baz": 7}]
|
||||
},
|
||||
{
|
||||
"expression": "foo[].bar[].[baz, qux]",
|
||||
"result": [[1, 2], [3, 4], [5, 6], [7, 8]]
|
||||
},
|
||||
{
|
||||
"expression": "foo[].bar[].[baz]",
|
||||
"result": [[1], [3], [5], [7]]
|
||||
},
|
||||
{
|
||||
"expression": "foo[].bar[].[baz, qux][]",
|
||||
"result": [1, 2, 3, 4, 5, 6, 7, 8]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {
|
||||
"foo": {
|
||||
"baz": [
|
||||
{
|
||||
"bar": "abc"
|
||||
}, {
|
||||
"bar": "def"
|
||||
}
|
||||
],
|
||||
"qux": ["zero"]
|
||||
}
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "foo.[baz[*].bar, qux[0]]",
|
||||
"result": [["abc", "def"], "zero"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {
|
||||
"foo": {
|
||||
"baz": [
|
||||
{
|
||||
"bar": "a",
|
||||
"bam": "b",
|
||||
"boo": "c"
|
||||
}, {
|
||||
"bar": "d",
|
||||
"bam": "e",
|
||||
"boo": "f"
|
||||
}
|
||||
],
|
||||
"qux": ["zero"]
|
||||
}
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "foo.[baz[*].[bar, boo], qux[0]]",
|
||||
"result": [[["a", "c" ], ["d", "f" ]], "zero"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {
|
||||
"foo": {
|
||||
"baz": [
|
||||
{
|
||||
"bar": "a",
|
||||
"bam": "b",
|
||||
"boo": "c"
|
||||
}, {
|
||||
"bar": "d",
|
||||
"bam": "e",
|
||||
"boo": "f"
|
||||
}
|
||||
],
|
||||
"qux": ["zero"]
|
||||
}
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "foo.[baz[*].not_there || baz[*].bar, qux[0]]",
|
||||
"result": [["a", "d"], "zero"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {"type": "object"},
|
||||
"cases": [
|
||||
{
|
||||
"comment": "Nested multiselect",
|
||||
"expression": "[[*],*]",
|
||||
"result": [null, ["object"]]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": [],
|
||||
"cases": [
|
||||
{
|
||||
"comment": "Nested multiselect",
|
||||
"expression": "[[*]]",
|
||||
"result": [[]]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
59
vendor/github.com/jmespath/go-jmespath/compliance/ormatch.json
generated
vendored
Normal file
59
vendor/github.com/jmespath/go-jmespath/compliance/ormatch.json
generated
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
[{
|
||||
"given":
|
||||
{"outer": {"foo": "foo", "bar": "bar", "baz": "baz"}},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "outer.foo || outer.bar",
|
||||
"result": "foo"
|
||||
},
|
||||
{
|
||||
"expression": "outer.foo||outer.bar",
|
||||
"result": "foo"
|
||||
},
|
||||
{
|
||||
"expression": "outer.bar || outer.baz",
|
||||
"result": "bar"
|
||||
},
|
||||
{
|
||||
"expression": "outer.bar||outer.baz",
|
||||
"result": "bar"
|
||||
},
|
||||
{
|
||||
"expression": "outer.bad || outer.foo",
|
||||
"result": "foo"
|
||||
},
|
||||
{
|
||||
"expression": "outer.bad||outer.foo",
|
||||
"result": "foo"
|
||||
},
|
||||
{
|
||||
"expression": "outer.foo || outer.bad",
|
||||
"result": "foo"
|
||||
},
|
||||
{
|
||||
"expression": "outer.foo||outer.bad",
|
||||
"result": "foo"
|
||||
},
|
||||
{
|
||||
"expression": "outer.bad || outer.alsobad",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "outer.bad||outer.alsobad",
|
||||
"result": null
|
||||
}
|
||||
]
|
||||
}, {
|
||||
"given":
|
||||
{"outer": {"foo": "foo", "bool": false, "empty_list": [], "empty_string": ""}},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "outer.empty_string || outer.foo",
|
||||
"result": "foo"
|
||||
},
|
||||
{
|
||||
"expression": "outer.nokey || outer.bool || outer.empty_list || outer.empty_string || outer.foo",
|
||||
"result": "foo"
|
||||
}
|
||||
]
|
||||
}]
|
131
vendor/github.com/jmespath/go-jmespath/compliance/pipe.json
generated
vendored
Normal file
131
vendor/github.com/jmespath/go-jmespath/compliance/pipe.json
generated
vendored
Normal file
|
@ -0,0 +1,131 @@
|
|||
[{
|
||||
"given": {
|
||||
"foo": {
|
||||
"bar": {
|
||||
"baz": "subkey"
|
||||
},
|
||||
"other": {
|
||||
"baz": "subkey"
|
||||
},
|
||||
"other2": {
|
||||
"baz": "subkey"
|
||||
},
|
||||
"other3": {
|
||||
"notbaz": ["a", "b", "c"]
|
||||
},
|
||||
"other4": {
|
||||
"notbaz": ["a", "b", "c"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "foo.*.baz | [0]",
|
||||
"result": "subkey"
|
||||
},
|
||||
{
|
||||
"expression": "foo.*.baz | [1]",
|
||||
"result": "subkey"
|
||||
},
|
||||
{
|
||||
"expression": "foo.*.baz | [2]",
|
||||
"result": "subkey"
|
||||
},
|
||||
{
|
||||
"expression": "foo.bar.* | [0]",
|
||||
"result": "subkey"
|
||||
},
|
||||
{
|
||||
"expression": "foo.*.notbaz | [*]",
|
||||
"result": [["a", "b", "c"], ["a", "b", "c"]]
|
||||
},
|
||||
{
|
||||
"expression": "{\"a\": foo.bar, \"b\": foo.other} | *.baz",
|
||||
"result": ["subkey", "subkey"]
|
||||
}
|
||||
]
|
||||
}, {
|
||||
"given": {
|
||||
"foo": {
|
||||
"bar": {
|
||||
"baz": "one"
|
||||
},
|
||||
"other": {
|
||||
"baz": "two"
|
||||
},
|
||||
"other2": {
|
||||
"baz": "three"
|
||||
},
|
||||
"other3": {
|
||||
"notbaz": ["a", "b", "c"]
|
||||
},
|
||||
"other4": {
|
||||
"notbaz": ["d", "e", "f"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "foo | bar",
|
||||
"result": {"baz": "one"}
|
||||
},
|
||||
{
|
||||
"expression": "foo | bar | baz",
|
||||
"result": "one"
|
||||
},
|
||||
{
|
||||
"expression": "foo|bar| baz",
|
||||
"result": "one"
|
||||
},
|
||||
{
|
||||
"expression": "not_there | [0]",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "not_there | [0]",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "[foo.bar, foo.other] | [0]",
|
||||
"result": {"baz": "one"}
|
||||
},
|
||||
{
|
||||
"expression": "{\"a\": foo.bar, \"b\": foo.other} | a",
|
||||
"result": {"baz": "one"}
|
||||
},
|
||||
{
|
||||
"expression": "{\"a\": foo.bar, \"b\": foo.other} | b",
|
||||
"result": {"baz": "two"}
|
||||
},
|
||||
{
|
||||
"expression": "foo.bam || foo.bar | baz",
|
||||
"result": "one"
|
||||
},
|
||||
{
|
||||
"expression": "foo | not_there || bar",
|
||||
"result": {"baz": "one"}
|
||||
}
|
||||
]
|
||||
}, {
|
||||
"given": {
|
||||
"foo": [{
|
||||
"bar": [{
|
||||
"baz": "one"
|
||||
}, {
|
||||
"baz": "two"
|
||||
}]
|
||||
}, {
|
||||
"bar": [{
|
||||
"baz": "three"
|
||||
}, {
|
||||
"baz": "four"
|
||||
}]
|
||||
}]
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "foo[*].bar[*] | [0][0]",
|
||||
"result": {"baz": "one"}
|
||||
}
|
||||
]
|
||||
}]
|
187
vendor/github.com/jmespath/go-jmespath/compliance/slice.json
generated
vendored
Normal file
187
vendor/github.com/jmespath/go-jmespath/compliance/slice.json
generated
vendored
Normal file
|
@ -0,0 +1,187 @@
|
|||
[{
|
||||
"given": {
|
||||
"foo": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
|
||||
"bar": {
|
||||
"baz": 1
|
||||
}
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "bar[0:10]",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "foo[0:10:1]",
|
||||
"result": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
},
|
||||
{
|
||||
"expression": "foo[0:10]",
|
||||
"result": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
},
|
||||
{
|
||||
"expression": "foo[0:10:]",
|
||||
"result": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
},
|
||||
{
|
||||
"expression": "foo[0::1]",
|
||||
"result": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
},
|
||||
{
|
||||
"expression": "foo[0::]",
|
||||
"result": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
},
|
||||
{
|
||||
"expression": "foo[0:]",
|
||||
"result": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
},
|
||||
{
|
||||
"expression": "foo[:10:1]",
|
||||
"result": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
},
|
||||
{
|
||||
"expression": "foo[::1]",
|
||||
"result": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
},
|
||||
{
|
||||
"expression": "foo[:10:]",
|
||||
"result": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
},
|
||||
{
|
||||
"expression": "foo[::]",
|
||||
"result": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
},
|
||||
{
|
||||
"expression": "foo[:]",
|
||||
"result": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
},
|
||||
{
|
||||
"expression": "foo[1:9]",
|
||||
"result": [1, 2, 3, 4, 5, 6, 7, 8]
|
||||
},
|
||||
{
|
||||
"expression": "foo[0:10:2]",
|
||||
"result": [0, 2, 4, 6, 8]
|
||||
},
|
||||
{
|
||||
"expression": "foo[5:]",
|
||||
"result": [5, 6, 7, 8, 9]
|
||||
},
|
||||
{
|
||||
"expression": "foo[5::2]",
|
||||
"result": [5, 7, 9]
|
||||
},
|
||||
{
|
||||
"expression": "foo[::2]",
|
||||
"result": [0, 2, 4, 6, 8]
|
||||
},
|
||||
{
|
||||
"expression": "foo[::-1]",
|
||||
"result": [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
|
||||
},
|
||||
{
|
||||
"expression": "foo[1::2]",
|
||||
"result": [1, 3, 5, 7, 9]
|
||||
},
|
||||
{
|
||||
"expression": "foo[10:0:-1]",
|
||||
"result": [9, 8, 7, 6, 5, 4, 3, 2, 1]
|
||||
},
|
||||
{
|
||||
"expression": "foo[10:5:-1]",
|
||||
"result": [9, 8, 7, 6]
|
||||
},
|
||||
{
|
||||
"expression": "foo[8:2:-2]",
|
||||
"result": [8, 6, 4]
|
||||
},
|
||||
{
|
||||
"expression": "foo[0:20]",
|
||||
"result": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
},
|
||||
{
|
||||
"expression": "foo[10:-20:-1]",
|
||||
"result": [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
|
||||
},
|
||||
{
|
||||
"expression": "foo[10:-20]",
|
||||
"result": []
|
||||
},
|
||||
{
|
||||
"expression": "foo[-4:-1]",
|
||||
"result": [6, 7, 8]
|
||||
},
|
||||
{
|
||||
"expression": "foo[:-5:-1]",
|
||||
"result": [9, 8, 7, 6]
|
||||
},
|
||||
{
|
||||
"expression": "foo[8:2:0]",
|
||||
"error": "invalid-value"
|
||||
},
|
||||
{
|
||||
"expression": "foo[8:2:0:1]",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "foo[8:2&]",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "foo[2:a:3]",
|
||||
"error": "syntax"
|
||||
}
|
||||
]
|
||||
}, {
|
||||
"given": {
|
||||
"foo": [{"a": 1}, {"a": 2}, {"a": 3}],
|
||||
"bar": [{"a": {"b": 1}}, {"a": {"b": 2}},
|
||||
{"a": {"b": 3}}],
|
||||
"baz": 50
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "foo[:2].a",
|
||||
"result": [1, 2]
|
||||
},
|
||||
{
|
||||
"expression": "foo[:2].b",
|
||||
"result": []
|
||||
},
|
||||
{
|
||||
"expression": "foo[:2].a.b",
|
||||
"result": []
|
||||
},
|
||||
{
|
||||
"expression": "bar[::-1].a.b",
|
||||
"result": [3, 2, 1]
|
||||
},
|
||||
{
|
||||
"expression": "bar[:2].a.b",
|
||||
"result": [1, 2]
|
||||
},
|
||||
{
|
||||
"expression": "baz[:2].a",
|
||||
"result": null
|
||||
}
|
||||
]
|
||||
}, {
|
||||
"given": [{"a": 1}, {"a": 2}, {"a": 3}],
|
||||
"cases": [
|
||||
{
|
||||
"expression": "[:]",
|
||||
"result": [{"a": 1}, {"a": 2}, {"a": 3}]
|
||||
},
|
||||
{
|
||||
"expression": "[:2].a",
|
||||
"result": [1, 2]
|
||||
},
|
||||
{
|
||||
"expression": "[::-1].a",
|
||||
"result": [3, 2, 1]
|
||||
},
|
||||
{
|
||||
"expression": "[:2].b",
|
||||
"result": []
|
||||
}
|
||||
]
|
||||
}]
|
616
vendor/github.com/jmespath/go-jmespath/compliance/syntax.json
generated
vendored
Normal file
616
vendor/github.com/jmespath/go-jmespath/compliance/syntax.json
generated
vendored
Normal file
|
@ -0,0 +1,616 @@
|
|||
[{
|
||||
"comment": "Dot syntax",
|
||||
"given": {"type": "object"},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "foo.bar",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "foo.1",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "foo.-11",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "foo",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "foo.",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "foo.",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": ".foo",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "foo..bar",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "foo.bar.",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "foo[.]",
|
||||
"error": "syntax"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"comment": "Simple token errors",
|
||||
"given": {"type": "object"},
|
||||
"cases": [
|
||||
{
|
||||
"expression": ".",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": ":",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": ",",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "]",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "[",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "}",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "{",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": ")",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "(",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "((&",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "a[",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "a]",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "a][",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "!",
|
||||
"error": "syntax"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"comment": "Boolean syntax errors",
|
||||
"given": {"type": "object"},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "![!(!",
|
||||
"error": "syntax"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"comment": "Wildcard syntax",
|
||||
"given": {"type": "object"},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "*",
|
||||
"result": ["object"]
|
||||
},
|
||||
{
|
||||
"expression": "*.*",
|
||||
"result": []
|
||||
},
|
||||
{
|
||||
"expression": "*.foo",
|
||||
"result": []
|
||||
},
|
||||
{
|
||||
"expression": "*[0]",
|
||||
"result": []
|
||||
},
|
||||
{
|
||||
"expression": ".*",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "*foo",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "*0",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "foo[*]bar",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "foo[*]*",
|
||||
"error": "syntax"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"comment": "Flatten syntax",
|
||||
"given": {"type": "object"},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "[]",
|
||||
"result": null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"comment": "Simple bracket syntax",
|
||||
"given": {"type": "object"},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "[0]",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "[*]",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "*.[0]",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "*.[\"0\"]",
|
||||
"result": [[null]]
|
||||
},
|
||||
{
|
||||
"expression": "[*].bar",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "[*][0]",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "foo[#]",
|
||||
"error": "syntax"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"comment": "Multi-select list syntax",
|
||||
"given": {"type": "object"},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "foo[0]",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"comment": "Valid multi-select of a list",
|
||||
"expression": "foo[0, 1]",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "foo.[0]",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "foo.[*]",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"comment": "Multi-select of a list with trailing comma",
|
||||
"expression": "foo[0, ]",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"comment": "Multi-select of a list with trailing comma and no close",
|
||||
"expression": "foo[0,",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"comment": "Multi-select of a list with trailing comma and no close",
|
||||
"expression": "foo.[a",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"comment": "Multi-select of a list with extra comma",
|
||||
"expression": "foo[0,, 1]",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"comment": "Multi-select of a list using an identifier index",
|
||||
"expression": "foo[abc]",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"comment": "Multi-select of a list using identifier indices",
|
||||
"expression": "foo[abc, def]",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"comment": "Multi-select of a list using an identifier index",
|
||||
"expression": "foo[abc, 1]",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"comment": "Multi-select of a list using an identifier index with trailing comma",
|
||||
"expression": "foo[abc, ]",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"comment": "Valid multi-select of a hash using an identifier index",
|
||||
"expression": "foo.[abc]",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"comment": "Valid multi-select of a hash",
|
||||
"expression": "foo.[abc, def]",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"comment": "Multi-select of a hash using a numeric index",
|
||||
"expression": "foo.[abc, 1]",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"comment": "Multi-select of a hash with a trailing comma",
|
||||
"expression": "foo.[abc, ]",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"comment": "Multi-select of a hash with extra commas",
|
||||
"expression": "foo.[abc,, def]",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"comment": "Multi-select of a hash using number indices",
|
||||
"expression": "foo.[0, 1]",
|
||||
"error": "syntax"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"comment": "Multi-select hash syntax",
|
||||
"given": {"type": "object"},
|
||||
"cases": [
|
||||
{
|
||||
"comment": "No key or value",
|
||||
"expression": "a{}",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"comment": "No closing token",
|
||||
"expression": "a{",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"comment": "Not a key value pair",
|
||||
"expression": "a{foo}",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"comment": "Missing value and closing character",
|
||||
"expression": "a{foo:",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"comment": "Missing closing character",
|
||||
"expression": "a{foo: 0",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"comment": "Missing value",
|
||||
"expression": "a{foo:}",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"comment": "Trailing comma and no closing character",
|
||||
"expression": "a{foo: 0, ",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"comment": "Missing value with trailing comma",
|
||||
"expression": "a{foo: ,}",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"comment": "Accessing Array using an identifier",
|
||||
"expression": "a{foo: bar}",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "a{foo: 0}",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"comment": "Missing key-value pair",
|
||||
"expression": "a.{}",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"comment": "Not a key-value pair",
|
||||
"expression": "a.{foo}",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"comment": "Missing value",
|
||||
"expression": "a.{foo:}",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"comment": "Missing value with trailing comma",
|
||||
"expression": "a.{foo: ,}",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"comment": "Valid multi-select hash extraction",
|
||||
"expression": "a.{foo: bar}",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"comment": "Valid multi-select hash extraction",
|
||||
"expression": "a.{foo: bar, baz: bam}",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"comment": "Trailing comma",
|
||||
"expression": "a.{foo: bar, }",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"comment": "Missing key in second key-value pair",
|
||||
"expression": "a.{foo: bar, baz}",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"comment": "Missing value in second key-value pair",
|
||||
"expression": "a.{foo: bar, baz:}",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"comment": "Trailing comma",
|
||||
"expression": "a.{foo: bar, baz: bam, }",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"comment": "Nested multi select",
|
||||
"expression": "{\"\\\\\":{\" \":*}}",
|
||||
"result": {"\\": {" ": ["object"]}}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"comment": "Or expressions",
|
||||
"given": {"type": "object"},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "foo || bar",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "foo ||",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "foo.|| bar",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": " || foo",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "foo || || foo",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "foo.[a || b]",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "foo.[a ||]",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "\"foo",
|
||||
"error": "syntax"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"comment": "Filter expressions",
|
||||
"given": {"type": "object"},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "foo[?bar==`\"baz\"`]",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "foo[? bar == `\"baz\"` ]",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "foo[ ?bar==`\"baz\"`]",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "foo[?bar==]",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "foo[?==]",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "foo[?==bar]",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "foo[?bar==baz?]",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "foo[?a.b.c==d.e.f]",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "foo[?bar==`[0, 1, 2]`]",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "foo[?bar==`[\"a\", \"b\", \"c\"]`]",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"comment": "Literal char not escaped",
|
||||
"expression": "foo[?bar==`[\"foo`bar\"]`]",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"comment": "Literal char escaped",
|
||||
"expression": "foo[?bar==`[\"foo\\`bar\"]`]",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"comment": "Unknown comparator",
|
||||
"expression": "foo[?bar<>baz]",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"comment": "Unknown comparator",
|
||||
"expression": "foo[?bar^baz]",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "foo[bar==baz]",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"comment": "Quoted identifier in filter expression no spaces",
|
||||
"expression": "[?\"\\\\\">`\"foo\"`]",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"comment": "Quoted identifier in filter expression with spaces",
|
||||
"expression": "[?\"\\\\\" > `\"foo\"`]",
|
||||
"result": null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"comment": "Filter expression errors",
|
||||
"given": {"type": "object"},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "bar.`\"anything\"`",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "bar.baz.noexists.`\"literal\"`",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"comment": "Literal wildcard projection",
|
||||
"expression": "foo[*].`\"literal\"`",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "foo[*].name.`\"literal\"`",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "foo[].name.`\"literal\"`",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "foo[].name.`\"literal\"`.`\"subliteral\"`",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"comment": "Projecting a literal onto an empty list",
|
||||
"expression": "foo[*].name.noexist.`\"literal\"`",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "foo[].name.noexist.`\"literal\"`",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"expression": "twolen[*].`\"foo\"`",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"comment": "Two level projection of a literal",
|
||||
"expression": "twolen[*].threelen[*].`\"bar\"`",
|
||||
"error": "syntax"
|
||||
},
|
||||
{
|
||||
"comment": "Two level flattened projection of a literal",
|
||||
"expression": "twolen[].threelen[].`\"bar\"`",
|
||||
"error": "syntax"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"comment": "Identifiers",
|
||||
"given": {"type": "object"},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "foo",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "\"foo\"",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "\"\\\\\"",
|
||||
"result": null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"comment": "Combined syntax",
|
||||
"given": [],
|
||||
"cases": [
|
||||
{
|
||||
"expression": "*||*|*|*",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "*[]||[*]",
|
||||
"result": []
|
||||
},
|
||||
{
|
||||
"expression": "[*.*]",
|
||||
"result": [null]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
38
vendor/github.com/jmespath/go-jmespath/compliance/unicode.json
generated
vendored
Normal file
38
vendor/github.com/jmespath/go-jmespath/compliance/unicode.json
generated
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
[
|
||||
{
|
||||
"given": {"foo": [{"✓": "✓"}, {"✓": "✗"}]},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "foo[].\"✓\"",
|
||||
"result": ["✓", "✗"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {"☯": true},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "\"☯\"",
|
||||
"result": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {"♪♫•*¨*•.¸¸❤¸¸.•*¨*•♫♪": true},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "\"♪♫•*¨*•.¸¸❤¸¸.•*¨*•♫♪\"",
|
||||
"result": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {"☃": true},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "\"☃\"",
|
||||
"result": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
460
vendor/github.com/jmespath/go-jmespath/compliance/wildcard.json
generated
vendored
Normal file
460
vendor/github.com/jmespath/go-jmespath/compliance/wildcard.json
generated
vendored
Normal file
|
@ -0,0 +1,460 @@
|
|||
[{
|
||||
"given": {
|
||||
"foo": {
|
||||
"bar": {
|
||||
"baz": "val"
|
||||
},
|
||||
"other": {
|
||||
"baz": "val"
|
||||
},
|
||||
"other2": {
|
||||
"baz": "val"
|
||||
},
|
||||
"other3": {
|
||||
"notbaz": ["a", "b", "c"]
|
||||
},
|
||||
"other4": {
|
||||
"notbaz": ["a", "b", "c"]
|
||||
},
|
||||
"other5": {
|
||||
"other": {
|
||||
"a": 1,
|
||||
"b": 1,
|
||||
"c": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "foo.*.baz",
|
||||
"result": ["val", "val", "val"]
|
||||
},
|
||||
{
|
||||
"expression": "foo.bar.*",
|
||||
"result": ["val"]
|
||||
},
|
||||
{
|
||||
"expression": "foo.*.notbaz",
|
||||
"result": [["a", "b", "c"], ["a", "b", "c"]]
|
||||
},
|
||||
{
|
||||
"expression": "foo.*.notbaz[0]",
|
||||
"result": ["a", "a"]
|
||||
},
|
||||
{
|
||||
"expression": "foo.*.notbaz[-1]",
|
||||
"result": ["c", "c"]
|
||||
}
|
||||
]
|
||||
}, {
|
||||
"given": {
|
||||
"foo": {
|
||||
"first-1": {
|
||||
"second-1": "val"
|
||||
},
|
||||
"first-2": {
|
||||
"second-1": "val"
|
||||
},
|
||||
"first-3": {
|
||||
"second-1": "val"
|
||||
}
|
||||
}
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "foo.*",
|
||||
"result": [{"second-1": "val"}, {"second-1": "val"},
|
||||
{"second-1": "val"}]
|
||||
},
|
||||
{
|
||||
"expression": "foo.*.*",
|
||||
"result": [["val"], ["val"], ["val"]]
|
||||
},
|
||||
{
|
||||
"expression": "foo.*.*.*",
|
||||
"result": [[], [], []]
|
||||
},
|
||||
{
|
||||
"expression": "foo.*.*.*.*",
|
||||
"result": [[], [], []]
|
||||
}
|
||||
]
|
||||
}, {
|
||||
"given": {
|
||||
"foo": {
|
||||
"bar": "one"
|
||||
},
|
||||
"other": {
|
||||
"bar": "one"
|
||||
},
|
||||
"nomatch": {
|
||||
"notbar": "three"
|
||||
}
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "*.bar",
|
||||
"result": ["one", "one"]
|
||||
}
|
||||
]
|
||||
}, {
|
||||
"given": {
|
||||
"top1": {
|
||||
"sub1": {"foo": "one"}
|
||||
},
|
||||
"top2": {
|
||||
"sub1": {"foo": "one"}
|
||||
}
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "*",
|
||||
"result": [{"sub1": {"foo": "one"}},
|
||||
{"sub1": {"foo": "one"}}]
|
||||
},
|
||||
{
|
||||
"expression": "*.sub1",
|
||||
"result": [{"foo": "one"},
|
||||
{"foo": "one"}]
|
||||
},
|
||||
{
|
||||
"expression": "*.*",
|
||||
"result": [[{"foo": "one"}],
|
||||
[{"foo": "one"}]]
|
||||
},
|
||||
{
|
||||
"expression": "*.*.foo[]",
|
||||
"result": ["one", "one"]
|
||||
},
|
||||
{
|
||||
"expression": "*.sub1.foo",
|
||||
"result": ["one", "one"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given":
|
||||
{"foo": [{"bar": "one"}, {"bar": "two"}, {"bar": "three"}, {"notbar": "four"}]},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "foo[*].bar",
|
||||
"result": ["one", "two", "three"]
|
||||
},
|
||||
{
|
||||
"expression": "foo[*].notbar",
|
||||
"result": ["four"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given":
|
||||
[{"bar": "one"}, {"bar": "two"}, {"bar": "three"}, {"notbar": "four"}],
|
||||
"cases": [
|
||||
{
|
||||
"expression": "[*]",
|
||||
"result": [{"bar": "one"}, {"bar": "two"}, {"bar": "three"}, {"notbar": "four"}]
|
||||
},
|
||||
{
|
||||
"expression": "[*].bar",
|
||||
"result": ["one", "two", "three"]
|
||||
},
|
||||
{
|
||||
"expression": "[*].notbar",
|
||||
"result": ["four"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {
|
||||
"foo": {
|
||||
"bar": [
|
||||
{"baz": ["one", "two", "three"]},
|
||||
{"baz": ["four", "five", "six"]},
|
||||
{"baz": ["seven", "eight", "nine"]}
|
||||
]
|
||||
}
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "foo.bar[*].baz",
|
||||
"result": [["one", "two", "three"], ["four", "five", "six"], ["seven", "eight", "nine"]]
|
||||
},
|
||||
{
|
||||
"expression": "foo.bar[*].baz[0]",
|
||||
"result": ["one", "four", "seven"]
|
||||
},
|
||||
{
|
||||
"expression": "foo.bar[*].baz[1]",
|
||||
"result": ["two", "five", "eight"]
|
||||
},
|
||||
{
|
||||
"expression": "foo.bar[*].baz[2]",
|
||||
"result": ["three", "six", "nine"]
|
||||
},
|
||||
{
|
||||
"expression": "foo.bar[*].baz[3]",
|
||||
"result": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {
|
||||
"foo": {
|
||||
"bar": [["one", "two"], ["three", "four"]]
|
||||
}
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "foo.bar[*]",
|
||||
"result": [["one", "two"], ["three", "four"]]
|
||||
},
|
||||
{
|
||||
"expression": "foo.bar[0]",
|
||||
"result": ["one", "two"]
|
||||
},
|
||||
{
|
||||
"expression": "foo.bar[0][0]",
|
||||
"result": "one"
|
||||
},
|
||||
{
|
||||
"expression": "foo.bar[0][0][0]",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "foo.bar[0][0][0][0]",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "foo[0][0]",
|
||||
"result": null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {
|
||||
"foo": [
|
||||
{"bar": [{"kind": "basic"}, {"kind": "intermediate"}]},
|
||||
{"bar": [{"kind": "advanced"}, {"kind": "expert"}]},
|
||||
{"bar": "string"}
|
||||
]
|
||||
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "foo[*].bar[*].kind",
|
||||
"result": [["basic", "intermediate"], ["advanced", "expert"]]
|
||||
},
|
||||
{
|
||||
"expression": "foo[*].bar[0].kind",
|
||||
"result": ["basic", "advanced"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {
|
||||
"foo": [
|
||||
{"bar": {"kind": "basic"}},
|
||||
{"bar": {"kind": "intermediate"}},
|
||||
{"bar": {"kind": "advanced"}},
|
||||
{"bar": {"kind": "expert"}},
|
||||
{"bar": "string"}
|
||||
]
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "foo[*].bar.kind",
|
||||
"result": ["basic", "intermediate", "advanced", "expert"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {
|
||||
"foo": [{"bar": ["one", "two"]}, {"bar": ["three", "four"]}, {"bar": ["five"]}]
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "foo[*].bar[0]",
|
||||
"result": ["one", "three", "five"]
|
||||
},
|
||||
{
|
||||
"expression": "foo[*].bar[1]",
|
||||
"result": ["two", "four"]
|
||||
},
|
||||
{
|
||||
"expression": "foo[*].bar[2]",
|
||||
"result": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {
|
||||
"foo": [{"bar": []}, {"bar": []}, {"bar": []}]
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "foo[*].bar[0]",
|
||||
"result": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {
|
||||
"foo": [["one", "two"], ["three", "four"], ["five"]]
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "foo[*][0]",
|
||||
"result": ["one", "three", "five"]
|
||||
},
|
||||
{
|
||||
"expression": "foo[*][1]",
|
||||
"result": ["two", "four"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {
|
||||
"foo": [
|
||||
[
|
||||
["one", "two"], ["three", "four"]
|
||||
], [
|
||||
["five", "six"], ["seven", "eight"]
|
||||
], [
|
||||
["nine"], ["ten"]
|
||||
]
|
||||
]
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "foo[*][0]",
|
||||
"result": [["one", "two"], ["five", "six"], ["nine"]]
|
||||
},
|
||||
{
|
||||
"expression": "foo[*][1]",
|
||||
"result": [["three", "four"], ["seven", "eight"], ["ten"]]
|
||||
},
|
||||
{
|
||||
"expression": "foo[*][0][0]",
|
||||
"result": ["one", "five", "nine"]
|
||||
},
|
||||
{
|
||||
"expression": "foo[*][1][0]",
|
||||
"result": ["three", "seven", "ten"]
|
||||
},
|
||||
{
|
||||
"expression": "foo[*][0][1]",
|
||||
"result": ["two", "six"]
|
||||
},
|
||||
{
|
||||
"expression": "foo[*][1][1]",
|
||||
"result": ["four", "eight"]
|
||||
},
|
||||
{
|
||||
"expression": "foo[*][2]",
|
||||
"result": []
|
||||
},
|
||||
{
|
||||
"expression": "foo[*][2][2]",
|
||||
"result": []
|
||||
},
|
||||
{
|
||||
"expression": "bar[*]",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "bar[*].baz[*]",
|
||||
"result": null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {
|
||||
"string": "string",
|
||||
"hash": {"foo": "bar", "bar": "baz"},
|
||||
"number": 23,
|
||||
"nullvalue": null
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "string[*]",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "hash[*]",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "number[*]",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "nullvalue[*]",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "string[*].foo",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "hash[*].foo",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "number[*].foo",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "nullvalue[*].foo",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "nullvalue[*].foo[*].bar",
|
||||
"result": null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {
|
||||
"string": "string",
|
||||
"hash": {"foo": "val", "bar": "val"},
|
||||
"number": 23,
|
||||
"array": [1, 2, 3],
|
||||
"nullvalue": null
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "string.*",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "hash.*",
|
||||
"result": ["val", "val"]
|
||||
},
|
||||
{
|
||||
"expression": "number.*",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "array.*",
|
||||
"result": null
|
||||
},
|
||||
{
|
||||
"expression": "nullvalue.*",
|
||||
"result": null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"given": {
|
||||
"a": [0, 1, 2],
|
||||
"b": [0, 1, 2]
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"expression": "*[0]",
|
||||
"result": [0, 0]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
842
vendor/github.com/jmespath/go-jmespath/functions.go
generated
vendored
Normal file
842
vendor/github.com/jmespath/go-jmespath/functions.go
generated
vendored
Normal file
|
@ -0,0 +1,842 @@
|
|||
package jmespath
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
type jpFunction func(arguments []interface{}) (interface{}, error)
|
||||
|
||||
type jpType string
|
||||
|
||||
const (
|
||||
jpUnknown jpType = "unknown"
|
||||
jpNumber jpType = "number"
|
||||
jpString jpType = "string"
|
||||
jpArray jpType = "array"
|
||||
jpObject jpType = "object"
|
||||
jpArrayNumber jpType = "array[number]"
|
||||
jpArrayString jpType = "array[string]"
|
||||
jpExpref jpType = "expref"
|
||||
jpAny jpType = "any"
|
||||
)
|
||||
|
||||
type functionEntry struct {
|
||||
name string
|
||||
arguments []argSpec
|
||||
handler jpFunction
|
||||
hasExpRef bool
|
||||
}
|
||||
|
||||
type argSpec struct {
|
||||
types []jpType
|
||||
variadic bool
|
||||
}
|
||||
|
||||
type byExprString struct {
|
||||
intr *treeInterpreter
|
||||
node ASTNode
|
||||
items []interface{}
|
||||
hasError bool
|
||||
}
|
||||
|
||||
func (a *byExprString) Len() int {
|
||||
return len(a.items)
|
||||
}
|
||||
func (a *byExprString) Swap(i, j int) {
|
||||
a.items[i], a.items[j] = a.items[j], a.items[i]
|
||||
}
|
||||
func (a *byExprString) Less(i, j int) bool {
|
||||
first, err := a.intr.Execute(a.node, a.items[i])
|
||||
if err != nil {
|
||||
a.hasError = true
|
||||
// Return a dummy value.
|
||||
return true
|
||||
}
|
||||
ith, ok := first.(string)
|
||||
if !ok {
|
||||
a.hasError = true
|
||||
return true
|
||||
}
|
||||
second, err := a.intr.Execute(a.node, a.items[j])
|
||||
if err != nil {
|
||||
a.hasError = true
|
||||
// Return a dummy value.
|
||||
return true
|
||||
}
|
||||
jth, ok := second.(string)
|
||||
if !ok {
|
||||
a.hasError = true
|
||||
return true
|
||||
}
|
||||
return ith < jth
|
||||
}
|
||||
|
||||
type byExprFloat struct {
|
||||
intr *treeInterpreter
|
||||
node ASTNode
|
||||
items []interface{}
|
||||
hasError bool
|
||||
}
|
||||
|
||||
func (a *byExprFloat) Len() int {
|
||||
return len(a.items)
|
||||
}
|
||||
func (a *byExprFloat) Swap(i, j int) {
|
||||
a.items[i], a.items[j] = a.items[j], a.items[i]
|
||||
}
|
||||
func (a *byExprFloat) Less(i, j int) bool {
|
||||
first, err := a.intr.Execute(a.node, a.items[i])
|
||||
if err != nil {
|
||||
a.hasError = true
|
||||
// Return a dummy value.
|
||||
return true
|
||||
}
|
||||
ith, ok := first.(float64)
|
||||
if !ok {
|
||||
a.hasError = true
|
||||
return true
|
||||
}
|
||||
second, err := a.intr.Execute(a.node, a.items[j])
|
||||
if err != nil {
|
||||
a.hasError = true
|
||||
// Return a dummy value.
|
||||
return true
|
||||
}
|
||||
jth, ok := second.(float64)
|
||||
if !ok {
|
||||
a.hasError = true
|
||||
return true
|
||||
}
|
||||
return ith < jth
|
||||
}
|
||||
|
||||
type functionCaller struct {
|
||||
functionTable map[string]functionEntry
|
||||
}
|
||||
|
||||
func newFunctionCaller() *functionCaller {
|
||||
caller := &functionCaller{}
|
||||
caller.functionTable = map[string]functionEntry{
|
||||
"length": {
|
||||
name: "length",
|
||||
arguments: []argSpec{
|
||||
{types: []jpType{jpString, jpArray, jpObject}},
|
||||
},
|
||||
handler: jpfLength,
|
||||
},
|
||||
"starts_with": {
|
||||
name: "starts_with",
|
||||
arguments: []argSpec{
|
||||
{types: []jpType{jpString}},
|
||||
{types: []jpType{jpString}},
|
||||
},
|
||||
handler: jpfStartsWith,
|
||||
},
|
||||
"abs": {
|
||||
name: "abs",
|
||||
arguments: []argSpec{
|
||||
{types: []jpType{jpNumber}},
|
||||
},
|
||||
handler: jpfAbs,
|
||||
},
|
||||
"avg": {
|
||||
name: "avg",
|
||||
arguments: []argSpec{
|
||||
{types: []jpType{jpArrayNumber}},
|
||||
},
|
||||
handler: jpfAvg,
|
||||
},
|
||||
"ceil": {
|
||||
name: "ceil",
|
||||
arguments: []argSpec{
|
||||
{types: []jpType{jpNumber}},
|
||||
},
|
||||
handler: jpfCeil,
|
||||
},
|
||||
"contains": {
|
||||
name: "contains",
|
||||
arguments: []argSpec{
|
||||
{types: []jpType{jpArray, jpString}},
|
||||
{types: []jpType{jpAny}},
|
||||
},
|
||||
handler: jpfContains,
|
||||
},
|
||||
"ends_with": {
|
||||
name: "ends_with",
|
||||
arguments: []argSpec{
|
||||
{types: []jpType{jpString}},
|
||||
{types: []jpType{jpString}},
|
||||
},
|
||||
handler: jpfEndsWith,
|
||||
},
|
||||
"floor": {
|
||||
name: "floor",
|
||||
arguments: []argSpec{
|
||||
{types: []jpType{jpNumber}},
|
||||
},
|
||||
handler: jpfFloor,
|
||||
},
|
||||
"map": {
|
||||
name: "amp",
|
||||
arguments: []argSpec{
|
||||
{types: []jpType{jpExpref}},
|
||||
{types: []jpType{jpArray}},
|
||||
},
|
||||
handler: jpfMap,
|
||||
hasExpRef: true,
|
||||
},
|
||||
"max": {
|
||||
name: "max",
|
||||
arguments: []argSpec{
|
||||
{types: []jpType{jpArrayNumber, jpArrayString}},
|
||||
},
|
||||
handler: jpfMax,
|
||||
},
|
||||
"merge": {
|
||||
name: "merge",
|
||||
arguments: []argSpec{
|
||||
{types: []jpType{jpObject}, variadic: true},
|
||||
},
|
||||
handler: jpfMerge,
|
||||
},
|
||||
"max_by": {
|
||||
name: "max_by",
|
||||
arguments: []argSpec{
|
||||
{types: []jpType{jpArray}},
|
||||
{types: []jpType{jpExpref}},
|
||||
},
|
||||
handler: jpfMaxBy,
|
||||
hasExpRef: true,
|
||||
},
|
||||
"sum": {
|
||||
name: "sum",
|
||||
arguments: []argSpec{
|
||||
{types: []jpType{jpArrayNumber}},
|
||||
},
|
||||
handler: jpfSum,
|
||||
},
|
||||
"min": {
|
||||
name: "min",
|
||||
arguments: []argSpec{
|
||||
{types: []jpType{jpArrayNumber, jpArrayString}},
|
||||
},
|
||||
handler: jpfMin,
|
||||
},
|
||||
"min_by": {
|
||||
name: "min_by",
|
||||
arguments: []argSpec{
|
||||
{types: []jpType{jpArray}},
|
||||
{types: []jpType{jpExpref}},
|
||||
},
|
||||
handler: jpfMinBy,
|
||||
hasExpRef: true,
|
||||
},
|
||||
"type": {
|
||||
name: "type",
|
||||
arguments: []argSpec{
|
||||
{types: []jpType{jpAny}},
|
||||
},
|
||||
handler: jpfType,
|
||||
},
|
||||
"keys": {
|
||||
name: "keys",
|
||||
arguments: []argSpec{
|
||||
{types: []jpType{jpObject}},
|
||||
},
|
||||
handler: jpfKeys,
|
||||
},
|
||||
"values": {
|
||||
name: "values",
|
||||
arguments: []argSpec{
|
||||
{types: []jpType{jpObject}},
|
||||
},
|
||||
handler: jpfValues,
|
||||
},
|
||||
"sort": {
|
||||
name: "sort",
|
||||
arguments: []argSpec{
|
||||
{types: []jpType{jpArrayString, jpArrayNumber}},
|
||||
},
|
||||
handler: jpfSort,
|
||||
},
|
||||
"sort_by": {
|
||||
name: "sort_by",
|
||||
arguments: []argSpec{
|
||||
{types: []jpType{jpArray}},
|
||||
{types: []jpType{jpExpref}},
|
||||
},
|
||||
handler: jpfSortBy,
|
||||
hasExpRef: true,
|
||||
},
|
||||
"join": {
|
||||
name: "join",
|
||||
arguments: []argSpec{
|
||||
{types: []jpType{jpString}},
|
||||
{types: []jpType{jpArrayString}},
|
||||
},
|
||||
handler: jpfJoin,
|
||||
},
|
||||
"reverse": {
|
||||
name: "reverse",
|
||||
arguments: []argSpec{
|
||||
{types: []jpType{jpArray, jpString}},
|
||||
},
|
||||
handler: jpfReverse,
|
||||
},
|
||||
"to_array": {
|
||||
name: "to_array",
|
||||
arguments: []argSpec{
|
||||
{types: []jpType{jpAny}},
|
||||
},
|
||||
handler: jpfToArray,
|
||||
},
|
||||
"to_string": {
|
||||
name: "to_string",
|
||||
arguments: []argSpec{
|
||||
{types: []jpType{jpAny}},
|
||||
},
|
||||
handler: jpfToString,
|
||||
},
|
||||
"to_number": {
|
||||
name: "to_number",
|
||||
arguments: []argSpec{
|
||||
{types: []jpType{jpAny}},
|
||||
},
|
||||
handler: jpfToNumber,
|
||||
},
|
||||
"not_null": {
|
||||
name: "not_null",
|
||||
arguments: []argSpec{
|
||||
{types: []jpType{jpAny}, variadic: true},
|
||||
},
|
||||
handler: jpfNotNull,
|
||||
},
|
||||
}
|
||||
return caller
|
||||
}
|
||||
|
||||
func (e *functionEntry) resolveArgs(arguments []interface{}) ([]interface{}, error) {
|
||||
if len(e.arguments) == 0 {
|
||||
return arguments, nil
|
||||
}
|
||||
if !e.arguments[len(e.arguments)-1].variadic {
|
||||
if len(e.arguments) != len(arguments) {
|
||||
return nil, errors.New("incorrect number of args")
|
||||
}
|
||||
for i, spec := range e.arguments {
|
||||
userArg := arguments[i]
|
||||
err := spec.typeCheck(userArg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return arguments, nil
|
||||
}
|
||||
if len(arguments) < len(e.arguments) {
|
||||
return nil, errors.New("Invalid arity.")
|
||||
}
|
||||
return arguments, nil
|
||||
}
|
||||
|
||||
func (a *argSpec) typeCheck(arg interface{}) error {
|
||||
for _, t := range a.types {
|
||||
switch t {
|
||||
case jpNumber:
|
||||
if _, ok := arg.(float64); ok {
|
||||
return nil
|
||||
}
|
||||
case jpString:
|
||||
if _, ok := arg.(string); ok {
|
||||
return nil
|
||||
}
|
||||
case jpArray:
|
||||
if isSliceType(arg) {
|
||||
return nil
|
||||
}
|
||||
case jpObject:
|
||||
if _, ok := arg.(map[string]interface{}); ok {
|
||||
return nil
|
||||
}
|
||||
case jpArrayNumber:
|
||||
if _, ok := toArrayNum(arg); ok {
|
||||
return nil
|
||||
}
|
||||
case jpArrayString:
|
||||
if _, ok := toArrayStr(arg); ok {
|
||||
return nil
|
||||
}
|
||||
case jpAny:
|
||||
return nil
|
||||
case jpExpref:
|
||||
if _, ok := arg.(expRef); ok {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("Invalid type for: %v, expected: %#v", arg, a.types)
|
||||
}
|
||||
|
||||
func (f *functionCaller) CallFunction(name string, arguments []interface{}, intr *treeInterpreter) (interface{}, error) {
|
||||
entry, ok := f.functionTable[name]
|
||||
if !ok {
|
||||
return nil, errors.New("unknown function: " + name)
|
||||
}
|
||||
resolvedArgs, err := entry.resolveArgs(arguments)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if entry.hasExpRef {
|
||||
var extra []interface{}
|
||||
extra = append(extra, intr)
|
||||
resolvedArgs = append(extra, resolvedArgs...)
|
||||
}
|
||||
return entry.handler(resolvedArgs)
|
||||
}
|
||||
|
||||
func jpfAbs(arguments []interface{}) (interface{}, error) {
|
||||
num := arguments[0].(float64)
|
||||
return math.Abs(num), nil
|
||||
}
|
||||
|
||||
func jpfLength(arguments []interface{}) (interface{}, error) {
|
||||
arg := arguments[0]
|
||||
if c, ok := arg.(string); ok {
|
||||
return float64(utf8.RuneCountInString(c)), nil
|
||||
} else if isSliceType(arg) {
|
||||
v := reflect.ValueOf(arg)
|
||||
return float64(v.Len()), nil
|
||||
} else if c, ok := arg.(map[string]interface{}); ok {
|
||||
return float64(len(c)), nil
|
||||
}
|
||||
return nil, errors.New("could not compute length()")
|
||||
}
|
||||
|
||||
func jpfStartsWith(arguments []interface{}) (interface{}, error) {
|
||||
search := arguments[0].(string)
|
||||
prefix := arguments[1].(string)
|
||||
return strings.HasPrefix(search, prefix), nil
|
||||
}
|
||||
|
||||
func jpfAvg(arguments []interface{}) (interface{}, error) {
|
||||
// We've already type checked the value so we can safely use
|
||||
// type assertions.
|
||||
args := arguments[0].([]interface{})
|
||||
length := float64(len(args))
|
||||
numerator := 0.0
|
||||
for _, n := range args {
|
||||
numerator += n.(float64)
|
||||
}
|
||||
return numerator / length, nil
|
||||
}
|
||||
func jpfCeil(arguments []interface{}) (interface{}, error) {
|
||||
val := arguments[0].(float64)
|
||||
return math.Ceil(val), nil
|
||||
}
|
||||
func jpfContains(arguments []interface{}) (interface{}, error) {
|
||||
search := arguments[0]
|
||||
el := arguments[1]
|
||||
if searchStr, ok := search.(string); ok {
|
||||
if elStr, ok := el.(string); ok {
|
||||
return strings.Index(searchStr, elStr) != -1, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
// Otherwise this is a generic contains for []interface{}
|
||||
general := search.([]interface{})
|
||||
for _, item := range general {
|
||||
if item == el {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
func jpfEndsWith(arguments []interface{}) (interface{}, error) {
|
||||
search := arguments[0].(string)
|
||||
suffix := arguments[1].(string)
|
||||
return strings.HasSuffix(search, suffix), nil
|
||||
}
|
||||
func jpfFloor(arguments []interface{}) (interface{}, error) {
|
||||
val := arguments[0].(float64)
|
||||
return math.Floor(val), nil
|
||||
}
|
||||
func jpfMap(arguments []interface{}) (interface{}, error) {
|
||||
intr := arguments[0].(*treeInterpreter)
|
||||
exp := arguments[1].(expRef)
|
||||
node := exp.ref
|
||||
arr := arguments[2].([]interface{})
|
||||
mapped := make([]interface{}, 0, len(arr))
|
||||
for _, value := range arr {
|
||||
current, err := intr.Execute(node, value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mapped = append(mapped, current)
|
||||
}
|
||||
return mapped, nil
|
||||
}
|
||||
func jpfMax(arguments []interface{}) (interface{}, error) {
|
||||
if items, ok := toArrayNum(arguments[0]); ok {
|
||||
if len(items) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
if len(items) == 1 {
|
||||
return items[0], nil
|
||||
}
|
||||
best := items[0]
|
||||
for _, item := range items[1:] {
|
||||
if item > best {
|
||||
best = item
|
||||
}
|
||||
}
|
||||
return best, nil
|
||||
}
|
||||
// Otherwise we're dealing with a max() of strings.
|
||||
items, _ := toArrayStr(arguments[0])
|
||||
if len(items) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
if len(items) == 1 {
|
||||
return items[0], nil
|
||||
}
|
||||
best := items[0]
|
||||
for _, item := range items[1:] {
|
||||
if item > best {
|
||||
best = item
|
||||
}
|
||||
}
|
||||
return best, nil
|
||||
}
|
||||
func jpfMerge(arguments []interface{}) (interface{}, error) {
|
||||
final := make(map[string]interface{})
|
||||
for _, m := range arguments {
|
||||
mapped := m.(map[string]interface{})
|
||||
for key, value := range mapped {
|
||||
final[key] = value
|
||||
}
|
||||
}
|
||||
return final, nil
|
||||
}
|
||||
func jpfMaxBy(arguments []interface{}) (interface{}, error) {
|
||||
intr := arguments[0].(*treeInterpreter)
|
||||
arr := arguments[1].([]interface{})
|
||||
exp := arguments[2].(expRef)
|
||||
node := exp.ref
|
||||
if len(arr) == 0 {
|
||||
return nil, nil
|
||||
} else if len(arr) == 1 {
|
||||
return arr[0], nil
|
||||
}
|
||||
start, err := intr.Execute(node, arr[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch t := start.(type) {
|
||||
case float64:
|
||||
bestVal := t
|
||||
bestItem := arr[0]
|
||||
for _, item := range arr[1:] {
|
||||
result, err := intr.Execute(node, item)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
current, ok := result.(float64)
|
||||
if !ok {
|
||||
return nil, errors.New("invalid type, must be number")
|
||||
}
|
||||
if current > bestVal {
|
||||
bestVal = current
|
||||
bestItem = item
|
||||
}
|
||||
}
|
||||
return bestItem, nil
|
||||
case string:
|
||||
bestVal := t
|
||||
bestItem := arr[0]
|
||||
for _, item := range arr[1:] {
|
||||
result, err := intr.Execute(node, item)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
current, ok := result.(string)
|
||||
if !ok {
|
||||
return nil, errors.New("invalid type, must be string")
|
||||
}
|
||||
if current > bestVal {
|
||||
bestVal = current
|
||||
bestItem = item
|
||||
}
|
||||
}
|
||||
return bestItem, nil
|
||||
default:
|
||||
return nil, errors.New("invalid type, must be number of string")
|
||||
}
|
||||
}
|
||||
func jpfSum(arguments []interface{}) (interface{}, error) {
|
||||
items, _ := toArrayNum(arguments[0])
|
||||
sum := 0.0
|
||||
for _, item := range items {
|
||||
sum += item
|
||||
}
|
||||
return sum, nil
|
||||
}
|
||||
|
||||
func jpfMin(arguments []interface{}) (interface{}, error) {
|
||||
if items, ok := toArrayNum(arguments[0]); ok {
|
||||
if len(items) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
if len(items) == 1 {
|
||||
return items[0], nil
|
||||
}
|
||||
best := items[0]
|
||||
for _, item := range items[1:] {
|
||||
if item < best {
|
||||
best = item
|
||||
}
|
||||
}
|
||||
return best, nil
|
||||
}
|
||||
items, _ := toArrayStr(arguments[0])
|
||||
if len(items) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
if len(items) == 1 {
|
||||
return items[0], nil
|
||||
}
|
||||
best := items[0]
|
||||
for _, item := range items[1:] {
|
||||
if item < best {
|
||||
best = item
|
||||
}
|
||||
}
|
||||
return best, nil
|
||||
}
|
||||
|
||||
func jpfMinBy(arguments []interface{}) (interface{}, error) {
|
||||
intr := arguments[0].(*treeInterpreter)
|
||||
arr := arguments[1].([]interface{})
|
||||
exp := arguments[2].(expRef)
|
||||
node := exp.ref
|
||||
if len(arr) == 0 {
|
||||
return nil, nil
|
||||
} else if len(arr) == 1 {
|
||||
return arr[0], nil
|
||||
}
|
||||
start, err := intr.Execute(node, arr[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if t, ok := start.(float64); ok {
|
||||
bestVal := t
|
||||
bestItem := arr[0]
|
||||
for _, item := range arr[1:] {
|
||||
result, err := intr.Execute(node, item)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
current, ok := result.(float64)
|
||||
if !ok {
|
||||
return nil, errors.New("invalid type, must be number")
|
||||
}
|
||||
if current < bestVal {
|
||||
bestVal = current
|
||||
bestItem = item
|
||||
}
|
||||
}
|
||||
return bestItem, nil
|
||||
} else if t, ok := start.(string); ok {
|
||||
bestVal := t
|
||||
bestItem := arr[0]
|
||||
for _, item := range arr[1:] {
|
||||
result, err := intr.Execute(node, item)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
current, ok := result.(string)
|
||||
if !ok {
|
||||
return nil, errors.New("invalid type, must be string")
|
||||
}
|
||||
if current < bestVal {
|
||||
bestVal = current
|
||||
bestItem = item
|
||||
}
|
||||
}
|
||||
return bestItem, nil
|
||||
} else {
|
||||
return nil, errors.New("invalid type, must be number of string")
|
||||
}
|
||||
}
|
||||
func jpfType(arguments []interface{}) (interface{}, error) {
|
||||
arg := arguments[0]
|
||||
if _, ok := arg.(float64); ok {
|
||||
return "number", nil
|
||||
}
|
||||
if _, ok := arg.(string); ok {
|
||||
return "string", nil
|
||||
}
|
||||
if _, ok := arg.([]interface{}); ok {
|
||||
return "array", nil
|
||||
}
|
||||
if _, ok := arg.(map[string]interface{}); ok {
|
||||
return "object", nil
|
||||
}
|
||||
if arg == nil {
|
||||
return "null", nil
|
||||
}
|
||||
if arg == true || arg == false {
|
||||
return "boolean", nil
|
||||
}
|
||||
return nil, errors.New("unknown type")
|
||||
}
|
||||
func jpfKeys(arguments []interface{}) (interface{}, error) {
|
||||
arg := arguments[0].(map[string]interface{})
|
||||
collected := make([]interface{}, 0, len(arg))
|
||||
for key := range arg {
|
||||
collected = append(collected, key)
|
||||
}
|
||||
return collected, nil
|
||||
}
|
||||
func jpfValues(arguments []interface{}) (interface{}, error) {
|
||||
arg := arguments[0].(map[string]interface{})
|
||||
collected := make([]interface{}, 0, len(arg))
|
||||
for _, value := range arg {
|
||||
collected = append(collected, value)
|
||||
}
|
||||
return collected, nil
|
||||
}
|
||||
func jpfSort(arguments []interface{}) (interface{}, error) {
|
||||
if items, ok := toArrayNum(arguments[0]); ok {
|
||||
d := sort.Float64Slice(items)
|
||||
sort.Stable(d)
|
||||
final := make([]interface{}, len(d))
|
||||
for i, val := range d {
|
||||
final[i] = val
|
||||
}
|
||||
return final, nil
|
||||
}
|
||||
// Otherwise we're dealing with sort()'ing strings.
|
||||
items, _ := toArrayStr(arguments[0])
|
||||
d := sort.StringSlice(items)
|
||||
sort.Stable(d)
|
||||
final := make([]interface{}, len(d))
|
||||
for i, val := range d {
|
||||
final[i] = val
|
||||
}
|
||||
return final, nil
|
||||
}
|
||||
func jpfSortBy(arguments []interface{}) (interface{}, error) {
|
||||
intr := arguments[0].(*treeInterpreter)
|
||||
arr := arguments[1].([]interface{})
|
||||
exp := arguments[2].(expRef)
|
||||
node := exp.ref
|
||||
if len(arr) == 0 {
|
||||
return arr, nil
|
||||
} else if len(arr) == 1 {
|
||||
return arr, nil
|
||||
}
|
||||
start, err := intr.Execute(node, arr[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, ok := start.(float64); ok {
|
||||
sortable := &byExprFloat{intr, node, arr, false}
|
||||
sort.Stable(sortable)
|
||||
if sortable.hasError {
|
||||
return nil, errors.New("error in sort_by comparison")
|
||||
}
|
||||
return arr, nil
|
||||
} else if _, ok := start.(string); ok {
|
||||
sortable := &byExprString{intr, node, arr, false}
|
||||
sort.Stable(sortable)
|
||||
if sortable.hasError {
|
||||
return nil, errors.New("error in sort_by comparison")
|
||||
}
|
||||
return arr, nil
|
||||
} else {
|
||||
return nil, errors.New("invalid type, must be number of string")
|
||||
}
|
||||
}
|
||||
func jpfJoin(arguments []interface{}) (interface{}, error) {
|
||||
sep := arguments[0].(string)
|
||||
// We can't just do arguments[1].([]string), we have to
|
||||
// manually convert each item to a string.
|
||||
arrayStr := []string{}
|
||||
for _, item := range arguments[1].([]interface{}) {
|
||||
arrayStr = append(arrayStr, item.(string))
|
||||
}
|
||||
return strings.Join(arrayStr, sep), nil
|
||||
}
|
||||
func jpfReverse(arguments []interface{}) (interface{}, error) {
|
||||
if s, ok := arguments[0].(string); ok {
|
||||
r := []rune(s)
|
||||
for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
|
||||
r[i], r[j] = r[j], r[i]
|
||||
}
|
||||
return string(r), nil
|
||||
}
|
||||
items := arguments[0].([]interface{})
|
||||
length := len(items)
|
||||
reversed := make([]interface{}, length)
|
||||
for i, item := range items {
|
||||
reversed[length-(i+1)] = item
|
||||
}
|
||||
return reversed, nil
|
||||
}
|
||||
func jpfToArray(arguments []interface{}) (interface{}, error) {
|
||||
if _, ok := arguments[0].([]interface{}); ok {
|
||||
return arguments[0], nil
|
||||
}
|
||||
return arguments[:1:1], nil
|
||||
}
|
||||
func jpfToString(arguments []interface{}) (interface{}, error) {
|
||||
if v, ok := arguments[0].(string); ok {
|
||||
return v, nil
|
||||
}
|
||||
result, err := json.Marshal(arguments[0])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return string(result), nil
|
||||
}
|
||||
func jpfToNumber(arguments []interface{}) (interface{}, error) {
|
||||
arg := arguments[0]
|
||||
if v, ok := arg.(float64); ok {
|
||||
return v, nil
|
||||
}
|
||||
if v, ok := arg.(string); ok {
|
||||
conv, err := strconv.ParseFloat(v, 64)
|
||||
if err != nil {
|
||||
return nil, nil
|
||||
}
|
||||
return conv, nil
|
||||
}
|
||||
if _, ok := arg.([]interface{}); ok {
|
||||
return nil, nil
|
||||
}
|
||||
if _, ok := arg.(map[string]interface{}); ok {
|
||||
return nil, nil
|
||||
}
|
||||
if arg == nil {
|
||||
return nil, nil
|
||||
}
|
||||
if arg == true || arg == false {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, errors.New("unknown type")
|
||||
}
|
||||
func jpfNotNull(arguments []interface{}) (interface{}, error) {
|
||||
for _, arg := range arguments {
|
||||
if arg != nil {
|
||||
return arg, nil
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
13
vendor/github.com/jmespath/go-jmespath/fuzz/jmespath.go
generated
vendored
Normal file
13
vendor/github.com/jmespath/go-jmespath/fuzz/jmespath.go
generated
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
package jmespath
|
||||
|
||||
import "github.com/jmespath/go-jmespath"
|
||||
|
||||
// Fuzz will fuzz test the JMESPath parser.
|
||||
func Fuzz(data []byte) int {
|
||||
p := jmespath.NewParser()
|
||||
_, err := p.Parse(string(data))
|
||||
if err != nil {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
418
vendor/github.com/jmespath/go-jmespath/interpreter.go
generated
vendored
Normal file
418
vendor/github.com/jmespath/go-jmespath/interpreter.go
generated
vendored
Normal file
|
@ -0,0 +1,418 @@
|
|||
package jmespath
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"reflect"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
/* This is a tree based interpreter. It walks the AST and directly
|
||||
interprets the AST to search through a JSON document.
|
||||
*/
|
||||
|
||||
type treeInterpreter struct {
|
||||
fCall *functionCaller
|
||||
}
|
||||
|
||||
func newInterpreter() *treeInterpreter {
|
||||
interpreter := treeInterpreter{}
|
||||
interpreter.fCall = newFunctionCaller()
|
||||
return &interpreter
|
||||
}
|
||||
|
||||
type expRef struct {
|
||||
ref ASTNode
|
||||
}
|
||||
|
||||
// Execute takes an ASTNode and input data and interprets the AST directly.
|
||||
// It will produce the result of applying the JMESPath expression associated
|
||||
// with the ASTNode to the input data "value".
|
||||
func (intr *treeInterpreter) Execute(node ASTNode, value interface{}) (interface{}, error) {
|
||||
switch node.nodeType {
|
||||
case ASTComparator:
|
||||
left, err := intr.Execute(node.children[0], value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
right, err := intr.Execute(node.children[1], value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch node.value {
|
||||
case tEQ:
|
||||
return objsEqual(left, right), nil
|
||||
case tNE:
|
||||
return !objsEqual(left, right), nil
|
||||
}
|
||||
leftNum, ok := left.(float64)
|
||||
if !ok {
|
||||
return nil, nil
|
||||
}
|
||||
rightNum, ok := right.(float64)
|
||||
if !ok {
|
||||
return nil, nil
|
||||
}
|
||||
switch node.value {
|
||||
case tGT:
|
||||
return leftNum > rightNum, nil
|
||||
case tGTE:
|
||||
return leftNum >= rightNum, nil
|
||||
case tLT:
|
||||
return leftNum < rightNum, nil
|
||||
case tLTE:
|
||||
return leftNum <= rightNum, nil
|
||||
}
|
||||
case ASTExpRef:
|
||||
return expRef{ref: node.children[0]}, nil
|
||||
case ASTFunctionExpression:
|
||||
resolvedArgs := []interface{}{}
|
||||
for _, arg := range node.children {
|
||||
current, err := intr.Execute(arg, value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resolvedArgs = append(resolvedArgs, current)
|
||||
}
|
||||
return intr.fCall.CallFunction(node.value.(string), resolvedArgs, intr)
|
||||
case ASTField:
|
||||
if m, ok := value.(map[string]interface{}); ok {
|
||||
key := node.value.(string)
|
||||
return m[key], nil
|
||||
}
|
||||
return intr.fieldFromStruct(node.value.(string), value)
|
||||
case ASTFilterProjection:
|
||||
left, err := intr.Execute(node.children[0], value)
|
||||
if err != nil {
|
||||
return nil, nil
|
||||
}
|
||||
sliceType, ok := left.([]interface{})
|
||||
if !ok {
|
||||
if isSliceType(left) {
|
||||
return intr.filterProjectionWithReflection(node, left)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
compareNode := node.children[2]
|
||||
collected := []interface{}{}
|
||||
for _, element := range sliceType {
|
||||
result, err := intr.Execute(compareNode, element)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !isFalse(result) {
|
||||
current, err := intr.Execute(node.children[1], element)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if current != nil {
|
||||
collected = append(collected, current)
|
||||
}
|
||||
}
|
||||
}
|
||||
return collected, nil
|
||||
case ASTFlatten:
|
||||
left, err := intr.Execute(node.children[0], value)
|
||||
if err != nil {
|
||||
return nil, nil
|
||||
}
|
||||
sliceType, ok := left.([]interface{})
|
||||
if !ok {
|
||||
// If we can't type convert to []interface{}, there's
|
||||
// a chance this could still work via reflection if we're
|
||||
// dealing with user provided types.
|
||||
if isSliceType(left) {
|
||||
return intr.flattenWithReflection(left)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
flattened := []interface{}{}
|
||||
for _, element := range sliceType {
|
||||
if elementSlice, ok := element.([]interface{}); ok {
|
||||
flattened = append(flattened, elementSlice...)
|
||||
} else if isSliceType(element) {
|
||||
reflectFlat := []interface{}{}
|
||||
v := reflect.ValueOf(element)
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
reflectFlat = append(reflectFlat, v.Index(i).Interface())
|
||||
}
|
||||
flattened = append(flattened, reflectFlat...)
|
||||
} else {
|
||||
flattened = append(flattened, element)
|
||||
}
|
||||
}
|
||||
return flattened, nil
|
||||
case ASTIdentity, ASTCurrentNode:
|
||||
return value, nil
|
||||
case ASTIndex:
|
||||
if sliceType, ok := value.([]interface{}); ok {
|
||||
index := node.value.(int)
|
||||
if index < 0 {
|
||||
index += len(sliceType)
|
||||
}
|
||||
if index < len(sliceType) && index >= 0 {
|
||||
return sliceType[index], nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
// Otherwise try via reflection.
|
||||
rv := reflect.ValueOf(value)
|
||||
if rv.Kind() == reflect.Slice {
|
||||
index := node.value.(int)
|
||||
if index < 0 {
|
||||
index += rv.Len()
|
||||
}
|
||||
if index < rv.Len() && index >= 0 {
|
||||
v := rv.Index(index)
|
||||
return v.Interface(), nil
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
case ASTKeyValPair:
|
||||
return intr.Execute(node.children[0], value)
|
||||
case ASTLiteral:
|
||||
return node.value, nil
|
||||
case ASTMultiSelectHash:
|
||||
if value == nil {
|
||||
return nil, nil
|
||||
}
|
||||
collected := make(map[string]interface{})
|
||||
for _, child := range node.children {
|
||||
current, err := intr.Execute(child, value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
key := child.value.(string)
|
||||
collected[key] = current
|
||||
}
|
||||
return collected, nil
|
||||
case ASTMultiSelectList:
|
||||
if value == nil {
|
||||
return nil, nil
|
||||
}
|
||||
collected := []interface{}{}
|
||||
for _, child := range node.children {
|
||||
current, err := intr.Execute(child, value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
collected = append(collected, current)
|
||||
}
|
||||
return collected, nil
|
||||
case ASTOrExpression:
|
||||
matched, err := intr.Execute(node.children[0], value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if isFalse(matched) {
|
||||
matched, err = intr.Execute(node.children[1], value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return matched, nil
|
||||
case ASTAndExpression:
|
||||
matched, err := intr.Execute(node.children[0], value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if isFalse(matched) {
|
||||
return matched, nil
|
||||
}
|
||||
return intr.Execute(node.children[1], value)
|
||||
case ASTNotExpression:
|
||||
matched, err := intr.Execute(node.children[0], value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if isFalse(matched) {
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
case ASTPipe:
|
||||
result := value
|
||||
var err error
|
||||
for _, child := range node.children {
|
||||
result, err = intr.Execute(child, result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
case ASTProjection:
|
||||
left, err := intr.Execute(node.children[0], value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sliceType, ok := left.([]interface{})
|
||||
if !ok {
|
||||
if isSliceType(left) {
|
||||
return intr.projectWithReflection(node, left)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
collected := []interface{}{}
|
||||
var current interface{}
|
||||
for _, element := range sliceType {
|
||||
current, err = intr.Execute(node.children[1], element)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if current != nil {
|
||||
collected = append(collected, current)
|
||||
}
|
||||
}
|
||||
return collected, nil
|
||||
case ASTSubexpression, ASTIndexExpression:
|
||||
left, err := intr.Execute(node.children[0], value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return intr.Execute(node.children[1], left)
|
||||
case ASTSlice:
|
||||
sliceType, ok := value.([]interface{})
|
||||
if !ok {
|
||||
if isSliceType(value) {
|
||||
return intr.sliceWithReflection(node, value)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
parts := node.value.([]*int)
|
||||
sliceParams := make([]sliceParam, 3)
|
||||
for i, part := range parts {
|
||||
if part != nil {
|
||||
sliceParams[i].Specified = true
|
||||
sliceParams[i].N = *part
|
||||
}
|
||||
}
|
||||
return slice(sliceType, sliceParams)
|
||||
case ASTValueProjection:
|
||||
left, err := intr.Execute(node.children[0], value)
|
||||
if err != nil {
|
||||
return nil, nil
|
||||
}
|
||||
mapType, ok := left.(map[string]interface{})
|
||||
if !ok {
|
||||
return nil, nil
|
||||
}
|
||||
values := make([]interface{}, len(mapType))
|
||||
for _, value := range mapType {
|
||||
values = append(values, value)
|
||||
}
|
||||
collected := []interface{}{}
|
||||
for _, element := range values {
|
||||
current, err := intr.Execute(node.children[1], element)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if current != nil {
|
||||
collected = append(collected, current)
|
||||
}
|
||||
}
|
||||
return collected, nil
|
||||
}
|
||||
return nil, errors.New("Unknown AST node: " + node.nodeType.String())
|
||||
}
|
||||
|
||||
func (intr *treeInterpreter) fieldFromStruct(key string, value interface{}) (interface{}, error) {
|
||||
rv := reflect.ValueOf(value)
|
||||
first, n := utf8.DecodeRuneInString(key)
|
||||
fieldName := string(unicode.ToUpper(first)) + key[n:]
|
||||
if rv.Kind() == reflect.Struct {
|
||||
v := rv.FieldByName(fieldName)
|
||||
if !v.IsValid() {
|
||||
return nil, nil
|
||||
}
|
||||
return v.Interface(), nil
|
||||
} else if rv.Kind() == reflect.Ptr {
|
||||
// Handle multiple levels of indirection?
|
||||
if rv.IsNil() {
|
||||
return nil, nil
|
||||
}
|
||||
rv = rv.Elem()
|
||||
v := rv.FieldByName(fieldName)
|
||||
if !v.IsValid() {
|
||||
return nil, nil
|
||||
}
|
||||
return v.Interface(), nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (intr *treeInterpreter) flattenWithReflection(value interface{}) (interface{}, error) {
|
||||
v := reflect.ValueOf(value)
|
||||
flattened := []interface{}{}
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
element := v.Index(i).Interface()
|
||||
if reflect.TypeOf(element).Kind() == reflect.Slice {
|
||||
// Then insert the contents of the element
|
||||
// slice into the flattened slice,
|
||||
// i.e flattened = append(flattened, mySlice...)
|
||||
elementV := reflect.ValueOf(element)
|
||||
for j := 0; j < elementV.Len(); j++ {
|
||||
flattened = append(
|
||||
flattened, elementV.Index(j).Interface())
|
||||
}
|
||||
} else {
|
||||
flattened = append(flattened, element)
|
||||
}
|
||||
}
|
||||
return flattened, nil
|
||||
}
|
||||
|
||||
func (intr *treeInterpreter) sliceWithReflection(node ASTNode, value interface{}) (interface{}, error) {
|
||||
v := reflect.ValueOf(value)
|
||||
parts := node.value.([]*int)
|
||||
sliceParams := make([]sliceParam, 3)
|
||||
for i, part := range parts {
|
||||
if part != nil {
|
||||
sliceParams[i].Specified = true
|
||||
sliceParams[i].N = *part
|
||||
}
|
||||
}
|
||||
final := []interface{}{}
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
element := v.Index(i).Interface()
|
||||
final = append(final, element)
|
||||
}
|
||||
return slice(final, sliceParams)
|
||||
}
|
||||
|
||||
func (intr *treeInterpreter) filterProjectionWithReflection(node ASTNode, value interface{}) (interface{}, error) {
|
||||
compareNode := node.children[2]
|
||||
collected := []interface{}{}
|
||||
v := reflect.ValueOf(value)
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
element := v.Index(i).Interface()
|
||||
result, err := intr.Execute(compareNode, element)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !isFalse(result) {
|
||||
current, err := intr.Execute(node.children[1], element)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if current != nil {
|
||||
collected = append(collected, current)
|
||||
}
|
||||
}
|
||||
}
|
||||
return collected, nil
|
||||
}
|
||||
|
||||
func (intr *treeInterpreter) projectWithReflection(node ASTNode, value interface{}) (interface{}, error) {
|
||||
collected := []interface{}{}
|
||||
v := reflect.ValueOf(value)
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
element := v.Index(i).Interface()
|
||||
result, err := intr.Execute(node.children[1], element)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if result != nil {
|
||||
collected = append(collected, result)
|
||||
}
|
||||
}
|
||||
return collected, nil
|
||||
}
|
420
vendor/github.com/jmespath/go-jmespath/lexer.go
generated
vendored
Normal file
420
vendor/github.com/jmespath/go-jmespath/lexer.go
generated
vendored
Normal file
|
@ -0,0 +1,420 @@
|
|||
package jmespath
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
type token struct {
|
||||
tokenType tokType
|
||||
value string
|
||||
position int
|
||||
length int
|
||||
}
|
||||
|
||||
type tokType int
|
||||
|
||||
const eof = -1
|
||||
|
||||
// Lexer contains information about the expression being tokenized.
|
||||
type Lexer struct {
|
||||
expression string // The expression provided by the user.
|
||||
currentPos int // The current position in the string.
|
||||
lastWidth int // The width of the current rune. This
|
||||
buf bytes.Buffer // Internal buffer used for building up values.
|
||||
}
|
||||
|
||||
// SyntaxError is the main error used whenever a lexing or parsing error occurs.
|
||||
type SyntaxError struct {
|
||||
msg string // Error message displayed to user
|
||||
Expression string // Expression that generated a SyntaxError
|
||||
Offset int // The location in the string where the error occurred
|
||||
}
|
||||
|
||||
func (e SyntaxError) Error() string {
|
||||
// In the future, it would be good to underline the specific
|
||||
// location where the error occurred.
|
||||
return "SyntaxError: " + e.msg
|
||||
}
|
||||
|
||||
// HighlightLocation will show where the syntax error occurred.
|
||||
// It will place a "^" character on a line below the expression
|
||||
// at the point where the syntax error occurred.
|
||||
func (e SyntaxError) HighlightLocation() string {
|
||||
return e.Expression + "\n" + strings.Repeat(" ", e.Offset) + "^"
|
||||
}
|
||||
|
||||
//go:generate stringer -type=tokType
|
||||
const (
|
||||
tUnknown tokType = iota
|
||||
tStar
|
||||
tDot
|
||||
tFilter
|
||||
tFlatten
|
||||
tLparen
|
||||
tRparen
|
||||
tLbracket
|
||||
tRbracket
|
||||
tLbrace
|
||||
tRbrace
|
||||
tOr
|
||||
tPipe
|
||||
tNumber
|
||||
tUnquotedIdentifier
|
||||
tQuotedIdentifier
|
||||
tComma
|
||||
tColon
|
||||
tLT
|
||||
tLTE
|
||||
tGT
|
||||
tGTE
|
||||
tEQ
|
||||
tNE
|
||||
tJSONLiteral
|
||||
tStringLiteral
|
||||
tCurrent
|
||||
tExpref
|
||||
tAnd
|
||||
tNot
|
||||
tEOF
|
||||
)
|
||||
|
||||
var basicTokens = map[rune]tokType{
|
||||
'.': tDot,
|
||||
'*': tStar,
|
||||
',': tComma,
|
||||
':': tColon,
|
||||
'{': tLbrace,
|
||||
'}': tRbrace,
|
||||
']': tRbracket, // tLbracket not included because it could be "[]"
|
||||
'(': tLparen,
|
||||
')': tRparen,
|
||||
'@': tCurrent,
|
||||
}
|
||||
|
||||
// Bit mask for [a-zA-Z_] shifted down 64 bits to fit in a single uint64.
|
||||
// When using this bitmask just be sure to shift the rune down 64 bits
|
||||
// before checking against identifierStartBits.
|
||||
const identifierStartBits uint64 = 576460745995190270
|
||||
|
||||
// Bit mask for [a-zA-Z0-9], 128 bits -> 2 uint64s.
|
||||
var identifierTrailingBits = [2]uint64{287948901175001088, 576460745995190270}
|
||||
|
||||
var whiteSpace = map[rune]bool{
|
||||
' ': true, '\t': true, '\n': true, '\r': true,
|
||||
}
|
||||
|
||||
func (t token) String() string {
|
||||
return fmt.Sprintf("Token{%+v, %s, %d, %d}",
|
||||
t.tokenType, t.value, t.position, t.length)
|
||||
}
|
||||
|
||||
// NewLexer creates a new JMESPath lexer.
|
||||
func NewLexer() *Lexer {
|
||||
lexer := Lexer{}
|
||||
return &lexer
|
||||
}
|
||||
|
||||
func (lexer *Lexer) next() rune {
|
||||
if lexer.currentPos >= len(lexer.expression) {
|
||||
lexer.lastWidth = 0
|
||||
return eof
|
||||
}
|
||||
r, w := utf8.DecodeRuneInString(lexer.expression[lexer.currentPos:])
|
||||
lexer.lastWidth = w
|
||||
lexer.currentPos += w
|
||||
return r
|
||||
}
|
||||
|
||||
func (lexer *Lexer) back() {
|
||||
lexer.currentPos -= lexer.lastWidth
|
||||
}
|
||||
|
||||
func (lexer *Lexer) peek() rune {
|
||||
t := lexer.next()
|
||||
lexer.back()
|
||||
return t
|
||||
}
|
||||
|
||||
// tokenize takes an expression and returns corresponding tokens.
|
||||
func (lexer *Lexer) tokenize(expression string) ([]token, error) {
|
||||
var tokens []token
|
||||
lexer.expression = expression
|
||||
lexer.currentPos = 0
|
||||
lexer.lastWidth = 0
|
||||
loop:
|
||||
for {
|
||||
r := lexer.next()
|
||||
if identifierStartBits&(1<<(uint64(r)-64)) > 0 {
|
||||
t := lexer.consumeUnquotedIdentifier()
|
||||
tokens = append(tokens, t)
|
||||
} else if val, ok := basicTokens[r]; ok {
|
||||
// Basic single char token.
|
||||
t := token{
|
||||
tokenType: val,
|
||||
value: string(r),
|
||||
position: lexer.currentPos - lexer.lastWidth,
|
||||
length: 1,
|
||||
}
|
||||
tokens = append(tokens, t)
|
||||
} else if r == '-' || (r >= '0' && r <= '9') {
|
||||
t := lexer.consumeNumber()
|
||||
tokens = append(tokens, t)
|
||||
} else if r == '[' {
|
||||
t := lexer.consumeLBracket()
|
||||
tokens = append(tokens, t)
|
||||
} else if r == '"' {
|
||||
t, err := lexer.consumeQuotedIdentifier()
|
||||
if err != nil {
|
||||
return tokens, err
|
||||
}
|
||||
tokens = append(tokens, t)
|
||||
} else if r == '\'' {
|
||||
t, err := lexer.consumeRawStringLiteral()
|
||||
if err != nil {
|
||||
return tokens, err
|
||||
}
|
||||
tokens = append(tokens, t)
|
||||
} else if r == '`' {
|
||||
t, err := lexer.consumeLiteral()
|
||||
if err != nil {
|
||||
return tokens, err
|
||||
}
|
||||
tokens = append(tokens, t)
|
||||
} else if r == '|' {
|
||||
t := lexer.matchOrElse(r, '|', tOr, tPipe)
|
||||
tokens = append(tokens, t)
|
||||
} else if r == '<' {
|
||||
t := lexer.matchOrElse(r, '=', tLTE, tLT)
|
||||
tokens = append(tokens, t)
|
||||
} else if r == '>' {
|
||||
t := lexer.matchOrElse(r, '=', tGTE, tGT)
|
||||
tokens = append(tokens, t)
|
||||
} else if r == '!' {
|
||||
t := lexer.matchOrElse(r, '=', tNE, tNot)
|
||||
tokens = append(tokens, t)
|
||||
} else if r == '=' {
|
||||
t := lexer.matchOrElse(r, '=', tEQ, tUnknown)
|
||||
tokens = append(tokens, t)
|
||||
} else if r == '&' {
|
||||
t := lexer.matchOrElse(r, '&', tAnd, tExpref)
|
||||
tokens = append(tokens, t)
|
||||
} else if r == eof {
|
||||
break loop
|
||||
} else if _, ok := whiteSpace[r]; ok {
|
||||
// Ignore whitespace
|
||||
} else {
|
||||
return tokens, lexer.syntaxError(fmt.Sprintf("Unknown char: %s", strconv.QuoteRuneToASCII(r)))
|
||||
}
|
||||
}
|
||||
tokens = append(tokens, token{tEOF, "", len(lexer.expression), 0})
|
||||
return tokens, nil
|
||||
}
|
||||
|
||||
// Consume characters until the ending rune "r" is reached.
|
||||
// If the end of the expression is reached before seeing the
|
||||
// terminating rune "r", then an error is returned.
|
||||
// If no error occurs then the matching substring is returned.
|
||||
// The returned string will not include the ending rune.
|
||||
func (lexer *Lexer) consumeUntil(end rune) (string, error) {
|
||||
start := lexer.currentPos
|
||||
current := lexer.next()
|
||||
for current != end && current != eof {
|
||||
if current == '\\' && lexer.peek() != eof {
|
||||
lexer.next()
|
||||
}
|
||||
current = lexer.next()
|
||||
}
|
||||
if lexer.lastWidth == 0 {
|
||||
// Then we hit an EOF so we never reached the closing
|
||||
// delimiter.
|
||||
return "", SyntaxError{
|
||||
msg: "Unclosed delimiter: " + string(end),
|
||||
Expression: lexer.expression,
|
||||
Offset: len(lexer.expression),
|
||||
}
|
||||
}
|
||||
return lexer.expression[start : lexer.currentPos-lexer.lastWidth], nil
|
||||
}
|
||||
|
||||
func (lexer *Lexer) consumeLiteral() (token, error) {
|
||||
start := lexer.currentPos
|
||||
value, err := lexer.consumeUntil('`')
|
||||
if err != nil {
|
||||
return token{}, err
|
||||
}
|
||||
value = strings.Replace(value, "\\`", "`", -1)
|
||||
return token{
|
||||
tokenType: tJSONLiteral,
|
||||
value: value,
|
||||
position: start,
|
||||
length: len(value),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (lexer *Lexer) consumeRawStringLiteral() (token, error) {
|
||||
start := lexer.currentPos
|
||||
currentIndex := start
|
||||
current := lexer.next()
|
||||
for current != '\'' && lexer.peek() != eof {
|
||||
if current == '\\' && lexer.peek() == '\'' {
|
||||
chunk := lexer.expression[currentIndex : lexer.currentPos-1]
|
||||
lexer.buf.WriteString(chunk)
|
||||
lexer.buf.WriteString("'")
|
||||
lexer.next()
|
||||
currentIndex = lexer.currentPos
|
||||
}
|
||||
current = lexer.next()
|
||||
}
|
||||
if lexer.lastWidth == 0 {
|
||||
// Then we hit an EOF so we never reached the closing
|
||||
// delimiter.
|
||||
return token{}, SyntaxError{
|
||||
msg: "Unclosed delimiter: '",
|
||||
Expression: lexer.expression,
|
||||
Offset: len(lexer.expression),
|
||||
}
|
||||
}
|
||||
if currentIndex < lexer.currentPos {
|
||||
lexer.buf.WriteString(lexer.expression[currentIndex : lexer.currentPos-1])
|
||||
}
|
||||
value := lexer.buf.String()
|
||||
// Reset the buffer so it can reused again.
|
||||
lexer.buf.Reset()
|
||||
return token{
|
||||
tokenType: tStringLiteral,
|
||||
value: value,
|
||||
position: start,
|
||||
length: len(value),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (lexer *Lexer) syntaxError(msg string) SyntaxError {
|
||||
return SyntaxError{
|
||||
msg: msg,
|
||||
Expression: lexer.expression,
|
||||
Offset: lexer.currentPos - 1,
|
||||
}
|
||||
}
|
||||
|
||||
// Checks for a two char token, otherwise matches a single character
|
||||
// token. This is used whenever a two char token overlaps a single
|
||||
// char token, e.g. "||" -> tPipe, "|" -> tOr.
|
||||
func (lexer *Lexer) matchOrElse(first rune, second rune, matchedType tokType, singleCharType tokType) token {
|
||||
start := lexer.currentPos - lexer.lastWidth
|
||||
nextRune := lexer.next()
|
||||
var t token
|
||||
if nextRune == second {
|
||||
t = token{
|
||||
tokenType: matchedType,
|
||||
value: string(first) + string(second),
|
||||
position: start,
|
||||
length: 2,
|
||||
}
|
||||
} else {
|
||||
lexer.back()
|
||||
t = token{
|
||||
tokenType: singleCharType,
|
||||
value: string(first),
|
||||
position: start,
|
||||
length: 1,
|
||||
}
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
func (lexer *Lexer) consumeLBracket() token {
|
||||
// There's three options here:
|
||||
// 1. A filter expression "[?"
|
||||
// 2. A flatten operator "[]"
|
||||
// 3. A bare rbracket "["
|
||||
start := lexer.currentPos - lexer.lastWidth
|
||||
nextRune := lexer.next()
|
||||
var t token
|
||||
if nextRune == '?' {
|
||||
t = token{
|
||||
tokenType: tFilter,
|
||||
value: "[?",
|
||||
position: start,
|
||||
length: 2,
|
||||
}
|
||||
} else if nextRune == ']' {
|
||||
t = token{
|
||||
tokenType: tFlatten,
|
||||
value: "[]",
|
||||
position: start,
|
||||
length: 2,
|
||||
}
|
||||
} else {
|
||||
t = token{
|
||||
tokenType: tLbracket,
|
||||
value: "[",
|
||||
position: start,
|
||||
length: 1,
|
||||
}
|
||||
lexer.back()
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
func (lexer *Lexer) consumeQuotedIdentifier() (token, error) {
|
||||
start := lexer.currentPos
|
||||
value, err := lexer.consumeUntil('"')
|
||||
if err != nil {
|
||||
return token{}, err
|
||||
}
|
||||
var decoded string
|
||||
asJSON := []byte("\"" + value + "\"")
|
||||
if err := json.Unmarshal([]byte(asJSON), &decoded); err != nil {
|
||||
return token{}, err
|
||||
}
|
||||
return token{
|
||||
tokenType: tQuotedIdentifier,
|
||||
value: decoded,
|
||||
position: start - 1,
|
||||
length: len(decoded),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (lexer *Lexer) consumeUnquotedIdentifier() token {
|
||||
// Consume runes until we reach the end of an unquoted
|
||||
// identifier.
|
||||
start := lexer.currentPos - lexer.lastWidth
|
||||
for {
|
||||
r := lexer.next()
|
||||
if r < 0 || r > 128 || identifierTrailingBits[uint64(r)/64]&(1<<(uint64(r)%64)) == 0 {
|
||||
lexer.back()
|
||||
break
|
||||
}
|
||||
}
|
||||
value := lexer.expression[start:lexer.currentPos]
|
||||
return token{
|
||||
tokenType: tUnquotedIdentifier,
|
||||
value: value,
|
||||
position: start,
|
||||
length: lexer.currentPos - start,
|
||||
}
|
||||
}
|
||||
|
||||
func (lexer *Lexer) consumeNumber() token {
|
||||
// Consume runes until we reach something that's not a number.
|
||||
start := lexer.currentPos - lexer.lastWidth
|
||||
for {
|
||||
r := lexer.next()
|
||||
if r < '0' || r > '9' {
|
||||
lexer.back()
|
||||
break
|
||||
}
|
||||
}
|
||||
value := lexer.expression[start:lexer.currentPos]
|
||||
return token{
|
||||
tokenType: tNumber,
|
||||
value: value,
|
||||
position: start,
|
||||
length: lexer.currentPos - start,
|
||||
}
|
||||
}
|
603
vendor/github.com/jmespath/go-jmespath/parser.go
generated
vendored
Normal file
603
vendor/github.com/jmespath/go-jmespath/parser.go
generated
vendored
Normal file
|
@ -0,0 +1,603 @@
|
|||
package jmespath
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type astNodeType int
|
||||
|
||||
//go:generate stringer -type astNodeType
|
||||
const (
|
||||
ASTEmpty astNodeType = iota
|
||||
ASTComparator
|
||||
ASTCurrentNode
|
||||
ASTExpRef
|
||||
ASTFunctionExpression
|
||||
ASTField
|
||||
ASTFilterProjection
|
||||
ASTFlatten
|
||||
ASTIdentity
|
||||
ASTIndex
|
||||
ASTIndexExpression
|
||||
ASTKeyValPair
|
||||
ASTLiteral
|
||||
ASTMultiSelectHash
|
||||
ASTMultiSelectList
|
||||
ASTOrExpression
|
||||
ASTAndExpression
|
||||
ASTNotExpression
|
||||
ASTPipe
|
||||
ASTProjection
|
||||
ASTSubexpression
|
||||
ASTSlice
|
||||
ASTValueProjection
|
||||
)
|
||||
|
||||
// ASTNode represents the abstract syntax tree of a JMESPath expression.
|
||||
type ASTNode struct {
|
||||
nodeType astNodeType
|
||||
value interface{}
|
||||
children []ASTNode
|
||||
}
|
||||
|
||||
func (node ASTNode) String() string {
|
||||
return node.PrettyPrint(0)
|
||||
}
|
||||
|
||||
// PrettyPrint will pretty print the parsed AST.
|
||||
// The AST is an implementation detail and this pretty print
|
||||
// function is provided as a convenience method to help with
|
||||
// debugging. You should not rely on its output as the internal
|
||||
// structure of the AST may change at any time.
|
||||
func (node ASTNode) PrettyPrint(indent int) string {
|
||||
spaces := strings.Repeat(" ", indent)
|
||||
output := fmt.Sprintf("%s%s {\n", spaces, node.nodeType)
|
||||
nextIndent := indent + 2
|
||||
if node.value != nil {
|
||||
if converted, ok := node.value.(fmt.Stringer); ok {
|
||||
// Account for things like comparator nodes
|
||||
// that are enums with a String() method.
|
||||
output += fmt.Sprintf("%svalue: %s\n", strings.Repeat(" ", nextIndent), converted.String())
|
||||
} else {
|
||||
output += fmt.Sprintf("%svalue: %#v\n", strings.Repeat(" ", nextIndent), node.value)
|
||||
}
|
||||
}
|
||||
lastIndex := len(node.children)
|
||||
if lastIndex > 0 {
|
||||
output += fmt.Sprintf("%schildren: {\n", strings.Repeat(" ", nextIndent))
|
||||
childIndent := nextIndent + 2
|
||||
for _, elem := range node.children {
|
||||
output += elem.PrettyPrint(childIndent)
|
||||
}
|
||||
}
|
||||
output += fmt.Sprintf("%s}\n", spaces)
|
||||
return output
|
||||
}
|
||||
|
||||
var bindingPowers = map[tokType]int{
|
||||
tEOF: 0,
|
||||
tUnquotedIdentifier: 0,
|
||||
tQuotedIdentifier: 0,
|
||||
tRbracket: 0,
|
||||
tRparen: 0,
|
||||
tComma: 0,
|
||||
tRbrace: 0,
|
||||
tNumber: 0,
|
||||
tCurrent: 0,
|
||||
tExpref: 0,
|
||||
tColon: 0,
|
||||
tPipe: 1,
|
||||
tOr: 2,
|
||||
tAnd: 3,
|
||||
tEQ: 5,
|
||||
tLT: 5,
|
||||
tLTE: 5,
|
||||
tGT: 5,
|
||||
tGTE: 5,
|
||||
tNE: 5,
|
||||
tFlatten: 9,
|
||||
tStar: 20,
|
||||
tFilter: 21,
|
||||
tDot: 40,
|
||||
tNot: 45,
|
||||
tLbrace: 50,
|
||||
tLbracket: 55,
|
||||
tLparen: 60,
|
||||
}
|
||||
|
||||
// Parser holds state about the current expression being parsed.
|
||||
type Parser struct {
|
||||
expression string
|
||||
tokens []token
|
||||
index int
|
||||
}
|
||||
|
||||
// NewParser creates a new JMESPath parser.
|
||||
func NewParser() *Parser {
|
||||
p := Parser{}
|
||||
return &p
|
||||
}
|
||||
|
||||
// Parse will compile a JMESPath expression.
|
||||
func (p *Parser) Parse(expression string) (ASTNode, error) {
|
||||
lexer := NewLexer()
|
||||
p.expression = expression
|
||||
p.index = 0
|
||||
tokens, err := lexer.tokenize(expression)
|
||||
if err != nil {
|
||||
return ASTNode{}, err
|
||||
}
|
||||
p.tokens = tokens
|
||||
parsed, err := p.parseExpression(0)
|
||||
if err != nil {
|
||||
return ASTNode{}, err
|
||||
}
|
||||
if p.current() != tEOF {
|
||||
return ASTNode{}, p.syntaxError(fmt.Sprintf(
|
||||
"Unexpected token at the end of the expresssion: %s", p.current()))
|
||||
}
|
||||
return parsed, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseExpression(bindingPower int) (ASTNode, error) {
|
||||
var err error
|
||||
leftToken := p.lookaheadToken(0)
|
||||
p.advance()
|
||||
leftNode, err := p.nud(leftToken)
|
||||
if err != nil {
|
||||
return ASTNode{}, err
|
||||
}
|
||||
currentToken := p.current()
|
||||
for bindingPower < bindingPowers[currentToken] {
|
||||
p.advance()
|
||||
leftNode, err = p.led(currentToken, leftNode)
|
||||
if err != nil {
|
||||
return ASTNode{}, err
|
||||
}
|
||||
currentToken = p.current()
|
||||
}
|
||||
return leftNode, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseIndexExpression() (ASTNode, error) {
|
||||
if p.lookahead(0) == tColon || p.lookahead(1) == tColon {
|
||||
return p.parseSliceExpression()
|
||||
}
|
||||
indexStr := p.lookaheadToken(0).value
|
||||
parsedInt, err := strconv.Atoi(indexStr)
|
||||
if err != nil {
|
||||
return ASTNode{}, err
|
||||
}
|
||||
indexNode := ASTNode{nodeType: ASTIndex, value: parsedInt}
|
||||
p.advance()
|
||||
if err := p.match(tRbracket); err != nil {
|
||||
return ASTNode{}, err
|
||||
}
|
||||
return indexNode, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseSliceExpression() (ASTNode, error) {
|
||||
parts := []*int{nil, nil, nil}
|
||||
index := 0
|
||||
current := p.current()
|
||||
for current != tRbracket && index < 3 {
|
||||
if current == tColon {
|
||||
index++
|
||||
p.advance()
|
||||
} else if current == tNumber {
|
||||
parsedInt, err := strconv.Atoi(p.lookaheadToken(0).value)
|
||||
if err != nil {
|
||||
return ASTNode{}, err
|
||||
}
|
||||
parts[index] = &parsedInt
|
||||
p.advance()
|
||||
} else {
|
||||
return ASTNode{}, p.syntaxError(
|
||||
"Expected tColon or tNumber" + ", received: " + p.current().String())
|
||||
}
|
||||
current = p.current()
|
||||
}
|
||||
if err := p.match(tRbracket); err != nil {
|
||||
return ASTNode{}, err
|
||||
}
|
||||
return ASTNode{
|
||||
nodeType: ASTSlice,
|
||||
value: parts,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *Parser) match(tokenType tokType) error {
|
||||
if p.current() == tokenType {
|
||||
p.advance()
|
||||
return nil
|
||||
}
|
||||
return p.syntaxError("Expected " + tokenType.String() + ", received: " + p.current().String())
|
||||
}
|
||||
|
||||
func (p *Parser) led(tokenType tokType, node ASTNode) (ASTNode, error) {
|
||||
switch tokenType {
|
||||
case tDot:
|
||||
if p.current() != tStar {
|
||||
right, err := p.parseDotRHS(bindingPowers[tDot])
|
||||
return ASTNode{
|
||||
nodeType: ASTSubexpression,
|
||||
children: []ASTNode{node, right},
|
||||
}, err
|
||||
}
|
||||
p.advance()
|
||||
right, err := p.parseProjectionRHS(bindingPowers[tDot])
|
||||
return ASTNode{
|
||||
nodeType: ASTValueProjection,
|
||||
children: []ASTNode{node, right},
|
||||
}, err
|
||||
case tPipe:
|
||||
right, err := p.parseExpression(bindingPowers[tPipe])
|
||||
return ASTNode{nodeType: ASTPipe, children: []ASTNode{node, right}}, err
|
||||
case tOr:
|
||||
right, err := p.parseExpression(bindingPowers[tOr])
|
||||
return ASTNode{nodeType: ASTOrExpression, children: []ASTNode{node, right}}, err
|
||||
case tAnd:
|
||||
right, err := p.parseExpression(bindingPowers[tAnd])
|
||||
return ASTNode{nodeType: ASTAndExpression, children: []ASTNode{node, right}}, err
|
||||
case tLparen:
|
||||
name := node.value
|
||||
var args []ASTNode
|
||||
for p.current() != tRparen {
|
||||
expression, err := p.parseExpression(0)
|
||||
if err != nil {
|
||||
return ASTNode{}, err
|
||||
}
|
||||
if p.current() == tComma {
|
||||
if err := p.match(tComma); err != nil {
|
||||
return ASTNode{}, err
|
||||
}
|
||||
}
|
||||
args = append(args, expression)
|
||||
}
|
||||
if err := p.match(tRparen); err != nil {
|
||||
return ASTNode{}, err
|
||||
}
|
||||
return ASTNode{
|
||||
nodeType: ASTFunctionExpression,
|
||||
value: name,
|
||||
children: args,
|
||||
}, nil
|
||||
case tFilter:
|
||||
return p.parseFilter(node)
|
||||
case tFlatten:
|
||||
left := ASTNode{nodeType: ASTFlatten, children: []ASTNode{node}}
|
||||
right, err := p.parseProjectionRHS(bindingPowers[tFlatten])
|
||||
return ASTNode{
|
||||
nodeType: ASTProjection,
|
||||
children: []ASTNode{left, right},
|
||||
}, err
|
||||
case tEQ, tNE, tGT, tGTE, tLT, tLTE:
|
||||
right, err := p.parseExpression(bindingPowers[tokenType])
|
||||
if err != nil {
|
||||
return ASTNode{}, err
|
||||
}
|
||||
return ASTNode{
|
||||
nodeType: ASTComparator,
|
||||
value: tokenType,
|
||||
children: []ASTNode{node, right},
|
||||
}, nil
|
||||
case tLbracket:
|
||||
tokenType := p.current()
|
||||
var right ASTNode
|
||||
var err error
|
||||
if tokenType == tNumber || tokenType == tColon {
|
||||
right, err = p.parseIndexExpression()
|
||||
if err != nil {
|
||||
return ASTNode{}, err
|
||||
}
|
||||
return p.projectIfSlice(node, right)
|
||||
}
|
||||
// Otherwise this is a projection.
|
||||
if err := p.match(tStar); err != nil {
|
||||
return ASTNode{}, err
|
||||
}
|
||||
if err := p.match(tRbracket); err != nil {
|
||||
return ASTNode{}, err
|
||||
}
|
||||
right, err = p.parseProjectionRHS(bindingPowers[tStar])
|
||||
if err != nil {
|
||||
return ASTNode{}, err
|
||||
}
|
||||
return ASTNode{
|
||||
nodeType: ASTProjection,
|
||||
children: []ASTNode{node, right},
|
||||
}, nil
|
||||
}
|
||||
return ASTNode{}, p.syntaxError("Unexpected token: " + tokenType.String())
|
||||
}
|
||||
|
||||
func (p *Parser) nud(token token) (ASTNode, error) {
|
||||
switch token.tokenType {
|
||||
case tJSONLiteral:
|
||||
var parsed interface{}
|
||||
err := json.Unmarshal([]byte(token.value), &parsed)
|
||||
if err != nil {
|
||||
return ASTNode{}, err
|
||||
}
|
||||
return ASTNode{nodeType: ASTLiteral, value: parsed}, nil
|
||||
case tStringLiteral:
|
||||
return ASTNode{nodeType: ASTLiteral, value: token.value}, nil
|
||||
case tUnquotedIdentifier:
|
||||
return ASTNode{
|
||||
nodeType: ASTField,
|
||||
value: token.value,
|
||||
}, nil
|
||||
case tQuotedIdentifier:
|
||||
node := ASTNode{nodeType: ASTField, value: token.value}
|
||||
if p.current() == tLparen {
|
||||
return ASTNode{}, p.syntaxErrorToken("Can't have quoted identifier as function name.", token)
|
||||
}
|
||||
return node, nil
|
||||
case tStar:
|
||||
left := ASTNode{nodeType: ASTIdentity}
|
||||
var right ASTNode
|
||||
var err error
|
||||
if p.current() == tRbracket {
|
||||
right = ASTNode{nodeType: ASTIdentity}
|
||||
} else {
|
||||
right, err = p.parseProjectionRHS(bindingPowers[tStar])
|
||||
}
|
||||
return ASTNode{nodeType: ASTValueProjection, children: []ASTNode{left, right}}, err
|
||||
case tFilter:
|
||||
return p.parseFilter(ASTNode{nodeType: ASTIdentity})
|
||||
case tLbrace:
|
||||
return p.parseMultiSelectHash()
|
||||
case tFlatten:
|
||||
left := ASTNode{
|
||||
nodeType: ASTFlatten,
|
||||
children: []ASTNode{{nodeType: ASTIdentity}},
|
||||
}
|
||||
right, err := p.parseProjectionRHS(bindingPowers[tFlatten])
|
||||
if err != nil {
|
||||
return ASTNode{}, err
|
||||
}
|
||||
return ASTNode{nodeType: ASTProjection, children: []ASTNode{left, right}}, nil
|
||||
case tLbracket:
|
||||
tokenType := p.current()
|
||||
//var right ASTNode
|
||||
if tokenType == tNumber || tokenType == tColon {
|
||||
right, err := p.parseIndexExpression()
|
||||
if err != nil {
|
||||
return ASTNode{}, nil
|
||||
}
|
||||
return p.projectIfSlice(ASTNode{nodeType: ASTIdentity}, right)
|
||||
} else if tokenType == tStar && p.lookahead(1) == tRbracket {
|
||||
p.advance()
|
||||
p.advance()
|
||||
right, err := p.parseProjectionRHS(bindingPowers[tStar])
|
||||
if err != nil {
|
||||
return ASTNode{}, err
|
||||
}
|
||||
return ASTNode{
|
||||
nodeType: ASTProjection,
|
||||
children: []ASTNode{{nodeType: ASTIdentity}, right},
|
||||
}, nil
|
||||
} else {
|
||||
return p.parseMultiSelectList()
|
||||
}
|
||||
case tCurrent:
|
||||
return ASTNode{nodeType: ASTCurrentNode}, nil
|
||||
case tExpref:
|
||||
expression, err := p.parseExpression(bindingPowers[tExpref])
|
||||
if err != nil {
|
||||
return ASTNode{}, err
|
||||
}
|
||||
return ASTNode{nodeType: ASTExpRef, children: []ASTNode{expression}}, nil
|
||||
case tNot:
|
||||
expression, err := p.parseExpression(bindingPowers[tNot])
|
||||
if err != nil {
|
||||
return ASTNode{}, err
|
||||
}
|
||||
return ASTNode{nodeType: ASTNotExpression, children: []ASTNode{expression}}, nil
|
||||
case tLparen:
|
||||
expression, err := p.parseExpression(0)
|
||||
if err != nil {
|
||||
return ASTNode{}, err
|
||||
}
|
||||
if err := p.match(tRparen); err != nil {
|
||||
return ASTNode{}, err
|
||||
}
|
||||
return expression, nil
|
||||
case tEOF:
|
||||
return ASTNode{}, p.syntaxErrorToken("Incomplete expression", token)
|
||||
}
|
||||
|
||||
return ASTNode{}, p.syntaxErrorToken("Invalid token: "+token.tokenType.String(), token)
|
||||
}
|
||||
|
||||
func (p *Parser) parseMultiSelectList() (ASTNode, error) {
|
||||
var expressions []ASTNode
|
||||
for {
|
||||
expression, err := p.parseExpression(0)
|
||||
if err != nil {
|
||||
return ASTNode{}, err
|
||||
}
|
||||
expressions = append(expressions, expression)
|
||||
if p.current() == tRbracket {
|
||||
break
|
||||
}
|
||||
err = p.match(tComma)
|
||||
if err != nil {
|
||||
return ASTNode{}, err
|
||||
}
|
||||
}
|
||||
err := p.match(tRbracket)
|
||||
if err != nil {
|
||||
return ASTNode{}, err
|
||||
}
|
||||
return ASTNode{
|
||||
nodeType: ASTMultiSelectList,
|
||||
children: expressions,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseMultiSelectHash() (ASTNode, error) {
|
||||
var children []ASTNode
|
||||
for {
|
||||
keyToken := p.lookaheadToken(0)
|
||||
if err := p.match(tUnquotedIdentifier); err != nil {
|
||||
if err := p.match(tQuotedIdentifier); err != nil {
|
||||
return ASTNode{}, p.syntaxError("Expected tQuotedIdentifier or tUnquotedIdentifier")
|
||||
}
|
||||
}
|
||||
keyName := keyToken.value
|
||||
err := p.match(tColon)
|
||||
if err != nil {
|
||||
return ASTNode{}, err
|
||||
}
|
||||
value, err := p.parseExpression(0)
|
||||
if err != nil {
|
||||
return ASTNode{}, err
|
||||
}
|
||||
node := ASTNode{
|
||||
nodeType: ASTKeyValPair,
|
||||
value: keyName,
|
||||
children: []ASTNode{value},
|
||||
}
|
||||
children = append(children, node)
|
||||
if p.current() == tComma {
|
||||
err := p.match(tComma)
|
||||
if err != nil {
|
||||
return ASTNode{}, nil
|
||||
}
|
||||
} else if p.current() == tRbrace {
|
||||
err := p.match(tRbrace)
|
||||
if err != nil {
|
||||
return ASTNode{}, nil
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
return ASTNode{
|
||||
nodeType: ASTMultiSelectHash,
|
||||
children: children,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *Parser) projectIfSlice(left ASTNode, right ASTNode) (ASTNode, error) {
|
||||
indexExpr := ASTNode{
|
||||
nodeType: ASTIndexExpression,
|
||||
children: []ASTNode{left, right},
|
||||
}
|
||||
if right.nodeType == ASTSlice {
|
||||
right, err := p.parseProjectionRHS(bindingPowers[tStar])
|
||||
return ASTNode{
|
||||
nodeType: ASTProjection,
|
||||
children: []ASTNode{indexExpr, right},
|
||||
}, err
|
||||
}
|
||||
return indexExpr, nil
|
||||
}
|
||||
func (p *Parser) parseFilter(node ASTNode) (ASTNode, error) {
|
||||
var right, condition ASTNode
|
||||
var err error
|
||||
condition, err = p.parseExpression(0)
|
||||
if err != nil {
|
||||
return ASTNode{}, err
|
||||
}
|
||||
if err := p.match(tRbracket); err != nil {
|
||||
return ASTNode{}, err
|
||||
}
|
||||
if p.current() == tFlatten {
|
||||
right = ASTNode{nodeType: ASTIdentity}
|
||||
} else {
|
||||
right, err = p.parseProjectionRHS(bindingPowers[tFilter])
|
||||
if err != nil {
|
||||
return ASTNode{}, err
|
||||
}
|
||||
}
|
||||
|
||||
return ASTNode{
|
||||
nodeType: ASTFilterProjection,
|
||||
children: []ASTNode{node, right, condition},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseDotRHS(bindingPower int) (ASTNode, error) {
|
||||
lookahead := p.current()
|
||||
if tokensOneOf([]tokType{tQuotedIdentifier, tUnquotedIdentifier, tStar}, lookahead) {
|
||||
return p.parseExpression(bindingPower)
|
||||
} else if lookahead == tLbracket {
|
||||
if err := p.match(tLbracket); err != nil {
|
||||
return ASTNode{}, err
|
||||
}
|
||||
return p.parseMultiSelectList()
|
||||
} else if lookahead == tLbrace {
|
||||
if err := p.match(tLbrace); err != nil {
|
||||
return ASTNode{}, err
|
||||
}
|
||||
return p.parseMultiSelectHash()
|
||||
}
|
||||
return ASTNode{}, p.syntaxError("Expected identifier, lbracket, or lbrace")
|
||||
}
|
||||
|
||||
func (p *Parser) parseProjectionRHS(bindingPower int) (ASTNode, error) {
|
||||
current := p.current()
|
||||
if bindingPowers[current] < 10 {
|
||||
return ASTNode{nodeType: ASTIdentity}, nil
|
||||
} else if current == tLbracket {
|
||||
return p.parseExpression(bindingPower)
|
||||
} else if current == tFilter {
|
||||
return p.parseExpression(bindingPower)
|
||||
} else if current == tDot {
|
||||
err := p.match(tDot)
|
||||
if err != nil {
|
||||
return ASTNode{}, err
|
||||
}
|
||||
return p.parseDotRHS(bindingPower)
|
||||
} else {
|
||||
return ASTNode{}, p.syntaxError("Error")
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Parser) lookahead(number int) tokType {
|
||||
return p.lookaheadToken(number).tokenType
|
||||
}
|
||||
|
||||
func (p *Parser) current() tokType {
|
||||
return p.lookahead(0)
|
||||
}
|
||||
|
||||
func (p *Parser) lookaheadToken(number int) token {
|
||||
return p.tokens[p.index+number]
|
||||
}
|
||||
|
||||
func (p *Parser) advance() {
|
||||
p.index++
|
||||
}
|
||||
|
||||
func tokensOneOf(elements []tokType, token tokType) bool {
|
||||
for _, elem := range elements {
|
||||
if elem == token {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (p *Parser) syntaxError(msg string) SyntaxError {
|
||||
return SyntaxError{
|
||||
msg: msg,
|
||||
Expression: p.expression,
|
||||
Offset: p.lookaheadToken(0).position,
|
||||
}
|
||||
}
|
||||
|
||||
// Create a SyntaxError based on the provided token.
|
||||
// This differs from syntaxError() which creates a SyntaxError
|
||||
// based on the current lookahead token.
|
||||
func (p *Parser) syntaxErrorToken(msg string, t token) SyntaxError {
|
||||
return SyntaxError{
|
||||
msg: msg,
|
||||
Expression: p.expression,
|
||||
Offset: t.position,
|
||||
}
|
||||
}
|
16
vendor/github.com/jmespath/go-jmespath/toktype_string.go
generated
vendored
Normal file
16
vendor/github.com/jmespath/go-jmespath/toktype_string.go
generated
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
// generated by stringer -type=tokType; DO NOT EDIT
|
||||
|
||||
package jmespath
|
||||
|
||||
import "fmt"
|
||||
|
||||
const _tokType_name = "tUnknowntStartDottFiltertFlattentLparentRparentLbrackettRbrackettLbracetRbracetOrtPipetNumbertUnquotedIdentifiertQuotedIdentifiertCommatColontLTtLTEtGTtGTEtEQtNEtJSONLiteraltStringLiteraltCurrenttExpreftAndtNottEOF"
|
||||
|
||||
var _tokType_index = [...]uint8{0, 8, 13, 17, 24, 32, 39, 46, 55, 64, 71, 78, 81, 86, 93, 112, 129, 135, 141, 144, 148, 151, 155, 158, 161, 173, 187, 195, 202, 206, 210, 214}
|
||||
|
||||
func (i tokType) String() string {
|
||||
if i < 0 || i >= tokType(len(_tokType_index)-1) {
|
||||
return fmt.Sprintf("tokType(%d)", i)
|
||||
}
|
||||
return _tokType_name[_tokType_index[i]:_tokType_index[i+1]]
|
||||
}
|
185
vendor/github.com/jmespath/go-jmespath/util.go
generated
vendored
Normal file
185
vendor/github.com/jmespath/go-jmespath/util.go
generated
vendored
Normal file
|
@ -0,0 +1,185 @@
|
|||
package jmespath
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// IsFalse determines if an object is false based on the JMESPath spec.
|
||||
// JMESPath defines false values to be any of:
|
||||
// - An empty string array, or hash.
|
||||
// - The boolean value false.
|
||||
// - nil
|
||||
func isFalse(value interface{}) bool {
|
||||
switch v := value.(type) {
|
||||
case bool:
|
||||
return !v
|
||||
case []interface{}:
|
||||
return len(v) == 0
|
||||
case map[string]interface{}:
|
||||
return len(v) == 0
|
||||
case string:
|
||||
return len(v) == 0
|
||||
case nil:
|
||||
return true
|
||||
}
|
||||
// Try the reflection cases before returning false.
|
||||
rv := reflect.ValueOf(value)
|
||||
switch rv.Kind() {
|
||||
case reflect.Struct:
|
||||
// A struct type will never be false, even if
|
||||
// all of its values are the zero type.
|
||||
return false
|
||||
case reflect.Slice, reflect.Map:
|
||||
return rv.Len() == 0
|
||||
case reflect.Ptr:
|
||||
if rv.IsNil() {
|
||||
return true
|
||||
}
|
||||
// If it's a pointer type, we'll try to deref the pointer
|
||||
// and evaluate the pointer value for isFalse.
|
||||
element := rv.Elem()
|
||||
return isFalse(element.Interface())
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ObjsEqual is a generic object equality check.
|
||||
// It will take two arbitrary objects and recursively determine
|
||||
// if they are equal.
|
||||
func objsEqual(left interface{}, right interface{}) bool {
|
||||
return reflect.DeepEqual(left, right)
|
||||
}
|
||||
|
||||
// SliceParam refers to a single part of a slice.
|
||||
// A slice consists of a start, a stop, and a step, similar to
|
||||
// python slices.
|
||||
type sliceParam struct {
|
||||
N int
|
||||
Specified bool
|
||||
}
|
||||
|
||||
// Slice supports [start:stop:step] style slicing that's supported in JMESPath.
|
||||
func slice(slice []interface{}, parts []sliceParam) ([]interface{}, error) {
|
||||
computed, err := computeSliceParams(len(slice), parts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
start, stop, step := computed[0], computed[1], computed[2]
|
||||
result := []interface{}{}
|
||||
if step > 0 {
|
||||
for i := start; i < stop; i += step {
|
||||
result = append(result, slice[i])
|
||||
}
|
||||
} else {
|
||||
for i := start; i > stop; i += step {
|
||||
result = append(result, slice[i])
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func computeSliceParams(length int, parts []sliceParam) ([]int, error) {
|
||||
var start, stop, step int
|
||||
if !parts[2].Specified {
|
||||
step = 1
|
||||
} else if parts[2].N == 0 {
|
||||
return nil, errors.New("Invalid slice, step cannot be 0")
|
||||
} else {
|
||||
step = parts[2].N
|
||||
}
|
||||
var stepValueNegative bool
|
||||
if step < 0 {
|
||||
stepValueNegative = true
|
||||
} else {
|
||||
stepValueNegative = false
|
||||
}
|
||||
|
||||
if !parts[0].Specified {
|
||||
if stepValueNegative {
|
||||
start = length - 1
|
||||
} else {
|
||||
start = 0
|
||||
}
|
||||
} else {
|
||||
start = capSlice(length, parts[0].N, step)
|
||||
}
|
||||
|
||||
if !parts[1].Specified {
|
||||
if stepValueNegative {
|
||||
stop = -1
|
||||
} else {
|
||||
stop = length
|
||||
}
|
||||
} else {
|
||||
stop = capSlice(length, parts[1].N, step)
|
||||
}
|
||||
return []int{start, stop, step}, nil
|
||||
}
|
||||
|
||||
func capSlice(length int, actual int, step int) int {
|
||||
if actual < 0 {
|
||||
actual += length
|
||||
if actual < 0 {
|
||||
if step < 0 {
|
||||
actual = -1
|
||||
} else {
|
||||
actual = 0
|
||||
}
|
||||
}
|
||||
} else if actual >= length {
|
||||
if step < 0 {
|
||||
actual = length - 1
|
||||
} else {
|
||||
actual = length
|
||||
}
|
||||
}
|
||||
return actual
|
||||
}
|
||||
|
||||
// ToArrayNum converts an empty interface type to a slice of float64.
|
||||
// If any element in the array cannot be converted, then nil is returned
|
||||
// along with a second value of false.
|
||||
func toArrayNum(data interface{}) ([]float64, bool) {
|
||||
// Is there a better way to do this with reflect?
|
||||
if d, ok := data.([]interface{}); ok {
|
||||
result := make([]float64, len(d))
|
||||
for i, el := range d {
|
||||
item, ok := el.(float64)
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
result[i] = item
|
||||
}
|
||||
return result, true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// ToArrayStr converts an empty interface type to a slice of strings.
|
||||
// If any element in the array cannot be converted, then nil is returned
|
||||
// along with a second value of false. If the input data could be entirely
|
||||
// converted, then the converted data, along with a second value of true,
|
||||
// will be returned.
|
||||
func toArrayStr(data interface{}) ([]string, bool) {
|
||||
// Is there a better way to do this with reflect?
|
||||
if d, ok := data.([]interface{}); ok {
|
||||
result := make([]string, len(d))
|
||||
for i, el := range d {
|
||||
item, ok := el.(string)
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
result[i] = item
|
||||
}
|
||||
return result, true
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func isSliceType(v interface{}) bool {
|
||||
if v == nil {
|
||||
return false
|
||||
}
|
||||
return reflect.TypeOf(v).Kind() == reflect.Slice
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue