aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/jmespath/go-jmespath
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/jmespath/go-jmespath')
-rw-r--r--vendor/github.com/jmespath/go-jmespath/LICENSE13
-rw-r--r--vendor/github.com/jmespath/go-jmespath/Makefile44
-rw-r--r--vendor/github.com/jmespath/go-jmespath/README.md7
-rw-r--r--vendor/github.com/jmespath/go-jmespath/api.go49
-rw-r--r--vendor/github.com/jmespath/go-jmespath/astnodetype_string.go16
-rw-r--r--vendor/github.com/jmespath/go-jmespath/functions.go842
-rw-r--r--vendor/github.com/jmespath/go-jmespath/interpreter.go418
-rw-r--r--vendor/github.com/jmespath/go-jmespath/lexer.go420
-rw-r--r--vendor/github.com/jmespath/go-jmespath/parser.go603
-rw-r--r--vendor/github.com/jmespath/go-jmespath/toktype_string.go16
-rw-r--r--vendor/github.com/jmespath/go-jmespath/util.go185
11 files changed, 0 insertions, 2613 deletions
diff --git a/vendor/github.com/jmespath/go-jmespath/LICENSE b/vendor/github.com/jmespath/go-jmespath/LICENSE
deleted file mode 100644
index b03310a..0000000
--- a/vendor/github.com/jmespath/go-jmespath/LICENSE
+++ /dev/null
@@ -1,13 +0,0 @@
-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.
diff --git a/vendor/github.com/jmespath/go-jmespath/Makefile b/vendor/github.com/jmespath/go-jmespath/Makefile
deleted file mode 100644
index a828d28..0000000
--- a/vendor/github.com/jmespath/go-jmespath/Makefile
+++ /dev/null
@@ -1,44 +0,0 @@
-
-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
diff --git a/vendor/github.com/jmespath/go-jmespath/README.md b/vendor/github.com/jmespath/go-jmespath/README.md
deleted file mode 100644
index 187ef67..0000000
--- a/vendor/github.com/jmespath/go-jmespath/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# go-jmespath - A JMESPath implementation in Go
-
-[![Build Status](https://img.shields.io/travis/jmespath/go-jmespath.svg)](https://travis-ci.org/jmespath/go-jmespath)
-
-
-
-See http://jmespath.org for more info.
diff --git a/vendor/github.com/jmespath/go-jmespath/api.go b/vendor/github.com/jmespath/go-jmespath/api.go
deleted file mode 100644
index 8e26ffe..0000000
--- a/vendor/github.com/jmespath/go-jmespath/api.go
+++ /dev/null
@@ -1,49 +0,0 @@
-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)
-}
diff --git a/vendor/github.com/jmespath/go-jmespath/astnodetype_string.go b/vendor/github.com/jmespath/go-jmespath/astnodetype_string.go
deleted file mode 100644
index 1cd2d23..0000000
--- a/vendor/github.com/jmespath/go-jmespath/astnodetype_string.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// 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]]
-}
diff --git a/vendor/github.com/jmespath/go-jmespath/functions.go b/vendor/github.com/jmespath/go-jmespath/functions.go
deleted file mode 100644
index 9b7cd89..0000000
--- a/vendor/github.com/jmespath/go-jmespath/functions.go
+++ /dev/null
@@ -1,842 +0,0 @@
-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
-}
diff --git a/vendor/github.com/jmespath/go-jmespath/interpreter.go b/vendor/github.com/jmespath/go-jmespath/interpreter.go
deleted file mode 100644
index 13c7460..0000000
--- a/vendor/github.com/jmespath/go-jmespath/interpreter.go
+++ /dev/null
@@ -1,418 +0,0 @@
-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
-}
diff --git a/vendor/github.com/jmespath/go-jmespath/lexer.go b/vendor/github.com/jmespath/go-jmespath/lexer.go
deleted file mode 100644
index 817900c..0000000
--- a/vendor/github.com/jmespath/go-jmespath/lexer.go
+++ /dev/null
@@ -1,420 +0,0 @@
-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,
- }
-}
diff --git a/vendor/github.com/jmespath/go-jmespath/parser.go b/vendor/github.com/jmespath/go-jmespath/parser.go
deleted file mode 100644
index 1240a17..0000000
--- a/vendor/github.com/jmespath/go-jmespath/parser.go
+++ /dev/null
@@ -1,603 +0,0 @@
-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,
- }
-}
diff --git a/vendor/github.com/jmespath/go-jmespath/toktype_string.go b/vendor/github.com/jmespath/go-jmespath/toktype_string.go
deleted file mode 100644
index dae79cb..0000000
--- a/vendor/github.com/jmespath/go-jmespath/toktype_string.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// 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]]
-}
diff --git a/vendor/github.com/jmespath/go-jmespath/util.go b/vendor/github.com/jmespath/go-jmespath/util.go
deleted file mode 100644
index ddc1b7d..0000000
--- a/vendor/github.com/jmespath/go-jmespath/util.go
+++ /dev/null
@@ -1,185 +0,0 @@
-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
-}