mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-21 10:51:29 +00:00
Add a dependency on github.com/exponent-io/jsonpath
This commit is contained in:
parent
5c9ac89b32
commit
a5ec367c30
4
Godeps/Godeps.json
generated
4
Godeps/Godeps.json
generated
@ -889,6 +889,10 @@
|
|||||||
"ImportPath": "github.com/evanphx/json-patch",
|
"ImportPath": "github.com/evanphx/json-patch",
|
||||||
"Rev": "465937c80b3c07a7c7ad20cc934898646a91c1de"
|
"Rev": "465937c80b3c07a7c7ad20cc934898646a91c1de"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "github.com/exponent-io/jsonpath",
|
||||||
|
"Rev": "d6023ce2651d8eafb5c75bb0c7167536102ec9f5"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/fsnotify/fsnotify",
|
"ImportPath": "github.com/fsnotify/fsnotify",
|
||||||
"Comment": "v1.3.1-1-gf12c623",
|
"Comment": "v1.3.1-1-gf12c623",
|
||||||
|
29
Godeps/LICENSES
generated
29
Godeps/LICENSES
generated
@ -31026,6 +31026,35 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
================================================================================
|
================================================================================
|
||||||
|
|
||||||
|
|
||||||
|
================================================================================
|
||||||
|
= vendor/github.com/exponent-io/jsonpath licensed under: =
|
||||||
|
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015 Exponent Labs LLC
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
|
= vendor/github.com/exponent-io/jsonpath/LICENSE 42f582355f11b1d4bc8615214b7f0c38 -
|
||||||
|
================================================================================
|
||||||
|
|
||||||
|
|
||||||
================================================================================
|
================================================================================
|
||||||
= vendor/github.com/fsnotify/fsnotify licensed under: =
|
= vendor/github.com/fsnotify/fsnotify licensed under: =
|
||||||
|
|
||||||
|
24
vendor/github.com/exponent-io/jsonpath/.gitignore
generated
vendored
Normal file
24
vendor/github.com/exponent-io/jsonpath/.gitignore
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||||
|
*.o
|
||||||
|
*.a
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Folders
|
||||||
|
_obj
|
||||||
|
_test
|
||||||
|
|
||||||
|
# Architecture specific extensions/prefixes
|
||||||
|
*.[568vq]
|
||||||
|
[568vq].out
|
||||||
|
|
||||||
|
*.cgo1.go
|
||||||
|
*.cgo2.c
|
||||||
|
_cgo_defun.c
|
||||||
|
_cgo_gotypes.go
|
||||||
|
_cgo_export.*
|
||||||
|
|
||||||
|
_testmain.go
|
||||||
|
|
||||||
|
*.exe
|
||||||
|
*.test
|
||||||
|
*.prof
|
5
vendor/github.com/exponent-io/jsonpath/.travis.yml
generated
vendored
Normal file
5
vendor/github.com/exponent-io/jsonpath/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
language: go
|
||||||
|
|
||||||
|
go:
|
||||||
|
- 1.5
|
||||||
|
- tip
|
21
vendor/github.com/exponent-io/jsonpath/LICENSE
generated
vendored
Normal file
21
vendor/github.com/exponent-io/jsonpath/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015 Exponent Labs LLC
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
66
vendor/github.com/exponent-io/jsonpath/README.md
generated
vendored
Normal file
66
vendor/github.com/exponent-io/jsonpath/README.md
generated
vendored
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
[](https://godoc.org/github.com/exponent-io/jsonpath)
|
||||||
|
[](https://travis-ci.org/exponent-io/jsonpath)
|
||||||
|
|
||||||
|
# jsonpath
|
||||||
|
|
||||||
|
This package extends the [json.Decoder](https://golang.org/pkg/encoding/json/#Decoder) to support navigating a stream of JSON tokens. You should be able to use this extended Decoder places where a json.Decoder would have been used.
|
||||||
|
|
||||||
|
This Decoder has the following enhancements...
|
||||||
|
* The [Scan](https://godoc.org/github.com/exponent-io/jsonpath/#Decoder.Scan) method supports scanning a JSON stream while extracting particular values along the way using [PathActions](https://godoc.org/github.com/exponent-io/jsonpath#PathActions).
|
||||||
|
* The [SeekTo](https://godoc.org/github.com/exponent-io/jsonpath#Decoder.SeekTo) method supports seeking forward in a JSON token stream to a particular path.
|
||||||
|
* The [Path](https://godoc.org/github.com/exponent-io/jsonpath#Decoder.Path) method returns the path of the most recently parsed token.
|
||||||
|
* The [Token](https://godoc.org/github.com/exponent-io/jsonpath#Decoder.Token) method has been modified to distinguish between strings that are object keys and strings that are values. Object key strings are returned as the [KeyString](https://godoc.org/github.com/exponent-io/jsonpath#KeyString) type rather than a native string.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
go get -u github.com/exponent-io/jsonpath
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
#### SeekTo
|
||||||
|
|
||||||
|
```go
|
||||||
|
import "github.com/exponent-io/jsonpath"
|
||||||
|
|
||||||
|
var j = []byte(`[
|
||||||
|
{"Space": "YCbCr", "Point": {"Y": 255, "Cb": 0, "Cr": -10}},
|
||||||
|
{"Space": "RGB", "Point": {"R": 98, "G": 218, "B": 255}}
|
||||||
|
]`)
|
||||||
|
|
||||||
|
w := json.NewDecoder(bytes.NewReader(j))
|
||||||
|
var v interface{}
|
||||||
|
|
||||||
|
w.SeekTo(1, "Point", "G")
|
||||||
|
w.Decode(&v) // v is 218
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Scan with PathActions
|
||||||
|
|
||||||
|
```go
|
||||||
|
var j = []byte(`{"colors":[
|
||||||
|
{"Space": "YCbCr", "Point": {"Y": 255, "Cb": 0, "Cr": -10, "A": 58}},
|
||||||
|
{"Space": "RGB", "Point": {"R": 98, "G": 218, "B": 255, "A": 231}}
|
||||||
|
]}`)
|
||||||
|
|
||||||
|
var actions PathActions
|
||||||
|
|
||||||
|
// Extract the value at Point.A
|
||||||
|
actions.Add(func(d *Decoder) error {
|
||||||
|
var alpha int
|
||||||
|
err := d.Decode(&alpha)
|
||||||
|
fmt.Printf("Alpha: %v\n", alpha)
|
||||||
|
return err
|
||||||
|
}, "Point", "A")
|
||||||
|
|
||||||
|
w := NewDecoder(bytes.NewReader(j))
|
||||||
|
w.SeekTo("colors", 0)
|
||||||
|
|
||||||
|
var ok = true
|
||||||
|
var err error
|
||||||
|
for ok {
|
||||||
|
ok, err = w.Scan(&actions)
|
||||||
|
if err != nil && err != io.EOF {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
210
vendor/github.com/exponent-io/jsonpath/decoder.go
generated
vendored
Normal file
210
vendor/github.com/exponent-io/jsonpath/decoder.go
generated
vendored
Normal file
@ -0,0 +1,210 @@
|
|||||||
|
package jsonpath
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
// KeyString is returned from Decoder.Token to represent each key in a JSON object value.
|
||||||
|
type KeyString string
|
||||||
|
|
||||||
|
// Decoder extends the Go runtime's encoding/json.Decoder to support navigating in a stream of JSON tokens.
|
||||||
|
type Decoder struct {
|
||||||
|
json.Decoder
|
||||||
|
|
||||||
|
path JsonPath
|
||||||
|
context jsonContext
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewDecoder creates a new instance of the extended JSON Decoder.
|
||||||
|
func NewDecoder(r io.Reader) *Decoder {
|
||||||
|
return &Decoder{Decoder: *json.NewDecoder(r)}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SeekTo causes the Decoder to move forward to a given path in the JSON structure.
|
||||||
|
//
|
||||||
|
// The path argument must consist of strings or integers. Each string specifies an JSON object key, and
|
||||||
|
// each integer specifies an index into a JSON array.
|
||||||
|
//
|
||||||
|
// Consider the JSON structure
|
||||||
|
//
|
||||||
|
// { "a": [0,"s",12e4,{"b":0,"v":35} ] }
|
||||||
|
//
|
||||||
|
// SeekTo("a",3,"v") will move to the value referenced by the "a" key in the current object,
|
||||||
|
// followed by a move to the 4th value (index 3) in the array, followed by a move to the value at key "v".
|
||||||
|
// In this example, a subsequent call to the decoder's Decode() would unmarshal the value 35.
|
||||||
|
//
|
||||||
|
// SeekTo returns a boolean value indicating whether a match was found.
|
||||||
|
//
|
||||||
|
// Decoder is intended to be used with a stream of tokens. As a result it navigates forward only.
|
||||||
|
func (d *Decoder) SeekTo(path ...interface{}) (bool, error) {
|
||||||
|
|
||||||
|
if len(path) == 0 {
|
||||||
|
return len(d.path) == 0, nil
|
||||||
|
}
|
||||||
|
last := len(path) - 1
|
||||||
|
if i, ok := path[last].(int); ok {
|
||||||
|
path[last] = i - 1
|
||||||
|
}
|
||||||
|
|
||||||
|
for {
|
||||||
|
if d.path.Equal(path) {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
_, err := d.Token()
|
||||||
|
if err == io.EOF {
|
||||||
|
return false, nil
|
||||||
|
} else if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decode reads the next JSON-encoded value from its input and stores it in the value pointed to by v. This is
|
||||||
|
// equivalent to encoding/json.Decode().
|
||||||
|
func (d *Decoder) Decode(v interface{}) error {
|
||||||
|
switch d.context {
|
||||||
|
case objValue:
|
||||||
|
d.context = objKey
|
||||||
|
break
|
||||||
|
case arrValue:
|
||||||
|
d.path.incTop()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return d.Decoder.Decode(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Path returns a slice of string and/or int values representing the path from the root of the JSON object to the
|
||||||
|
// position of the most-recently parsed token.
|
||||||
|
func (d *Decoder) Path() JsonPath {
|
||||||
|
p := make(JsonPath, len(d.path))
|
||||||
|
copy(p, d.path)
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
// Token is equivalent to the Token() method on json.Decoder. The primary difference is that it distinguishes
|
||||||
|
// between strings that are keys and and strings that are values. String tokens that are object keys are returned as a
|
||||||
|
// KeyString rather than as a native string.
|
||||||
|
func (d *Decoder) Token() (json.Token, error) {
|
||||||
|
t, err := d.Decoder.Token()
|
||||||
|
if err != nil {
|
||||||
|
return t, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if t == nil {
|
||||||
|
switch d.context {
|
||||||
|
case objValue:
|
||||||
|
d.context = objKey
|
||||||
|
break
|
||||||
|
case arrValue:
|
||||||
|
d.path.incTop()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return t, err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch t := t.(type) {
|
||||||
|
case json.Delim:
|
||||||
|
switch t {
|
||||||
|
case json.Delim('{'):
|
||||||
|
if d.context == arrValue {
|
||||||
|
d.path.incTop()
|
||||||
|
}
|
||||||
|
d.path.push("")
|
||||||
|
d.context = objKey
|
||||||
|
break
|
||||||
|
case json.Delim('}'):
|
||||||
|
d.path.pop()
|
||||||
|
d.context = d.path.inferContext()
|
||||||
|
break
|
||||||
|
case json.Delim('['):
|
||||||
|
if d.context == arrValue {
|
||||||
|
d.path.incTop()
|
||||||
|
}
|
||||||
|
d.path.push(-1)
|
||||||
|
d.context = arrValue
|
||||||
|
break
|
||||||
|
case json.Delim(']'):
|
||||||
|
d.path.pop()
|
||||||
|
d.context = d.path.inferContext()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case float64, json.Number, bool:
|
||||||
|
switch d.context {
|
||||||
|
case objValue:
|
||||||
|
d.context = objKey
|
||||||
|
break
|
||||||
|
case arrValue:
|
||||||
|
d.path.incTop()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case string:
|
||||||
|
switch d.context {
|
||||||
|
case objKey:
|
||||||
|
d.path.nameTop(t)
|
||||||
|
d.context = objValue
|
||||||
|
return KeyString(t), err
|
||||||
|
case objValue:
|
||||||
|
d.context = objKey
|
||||||
|
case arrValue:
|
||||||
|
d.path.incTop()
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return t, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scan moves forward over the JSON stream consuming all the tokens at the current level (current object, current array)
|
||||||
|
// invoking each matching PathAction along the way.
|
||||||
|
//
|
||||||
|
// Scan returns true if there are more contiguous values to scan (for example in an array).
|
||||||
|
func (d *Decoder) Scan(ext *PathActions) (bool, error) {
|
||||||
|
|
||||||
|
rootPath := d.Path()
|
||||||
|
|
||||||
|
// If this is an array path, increment the root path in our local copy.
|
||||||
|
if rootPath.inferContext() == arrValue {
|
||||||
|
rootPath.incTop()
|
||||||
|
}
|
||||||
|
|
||||||
|
for {
|
||||||
|
// advance the token position
|
||||||
|
_, err := d.Token()
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
match:
|
||||||
|
var relPath JsonPath
|
||||||
|
|
||||||
|
// capture the new JSON path
|
||||||
|
path := d.Path()
|
||||||
|
|
||||||
|
if len(path) > len(rootPath) {
|
||||||
|
// capture the path relative to where the scan started
|
||||||
|
relPath = path[len(rootPath):]
|
||||||
|
} else {
|
||||||
|
// if the path is not longer than the root, then we are done with this scan
|
||||||
|
// return boolean flag indicating if there are more items to scan at the same level
|
||||||
|
return d.Decoder.More(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// match the relative path against the path actions
|
||||||
|
if node := ext.node.match(relPath); node != nil {
|
||||||
|
if node.action != nil {
|
||||||
|
// we have a match so execute the action
|
||||||
|
err = node.action(d)
|
||||||
|
if err != nil {
|
||||||
|
return d.Decoder.More(), err
|
||||||
|
}
|
||||||
|
// The action may have advanced the decoder. If we are in an array, advancing it further would
|
||||||
|
// skip tokens. So, if we are scanning an array, jump to the top without advancing the token.
|
||||||
|
if d.path.inferContext() == arrValue && d.Decoder.More() {
|
||||||
|
goto match
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
67
vendor/github.com/exponent-io/jsonpath/path.go
generated
vendored
Normal file
67
vendor/github.com/exponent-io/jsonpath/path.go
generated
vendored
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
// Extends the Go runtime's json.Decoder enabling navigation of a stream of json tokens.
|
||||||
|
package jsonpath
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type jsonContext int
|
||||||
|
|
||||||
|
const (
|
||||||
|
none jsonContext = iota
|
||||||
|
objKey
|
||||||
|
objValue
|
||||||
|
arrValue
|
||||||
|
)
|
||||||
|
|
||||||
|
// AnyIndex can be used in a pattern to match any array index.
|
||||||
|
const AnyIndex = -2
|
||||||
|
|
||||||
|
// JsonPath is a slice of strings and/or integers. Each string specifies an JSON object key, and
|
||||||
|
// each integer specifies an index into a JSON array.
|
||||||
|
type JsonPath []interface{}
|
||||||
|
|
||||||
|
func (p *JsonPath) push(n interface{}) { *p = append(*p, n) }
|
||||||
|
func (p *JsonPath) pop() { *p = (*p)[:len(*p)-1] }
|
||||||
|
|
||||||
|
// increment the index at the top of the stack (must be an array index)
|
||||||
|
func (p *JsonPath) incTop() { (*p)[len(*p)-1] = (*p)[len(*p)-1].(int) + 1 }
|
||||||
|
|
||||||
|
// name the key at the top of the stack (must be an object key)
|
||||||
|
func (p *JsonPath) nameTop(n string) { (*p)[len(*p)-1] = n }
|
||||||
|
|
||||||
|
// infer the context from the item at the top of the stack
|
||||||
|
func (p *JsonPath) inferContext() jsonContext {
|
||||||
|
if len(*p) == 0 {
|
||||||
|
return none
|
||||||
|
}
|
||||||
|
t := (*p)[len(*p)-1]
|
||||||
|
switch t.(type) {
|
||||||
|
case string:
|
||||||
|
return objKey
|
||||||
|
case int:
|
||||||
|
return arrValue
|
||||||
|
default:
|
||||||
|
panic(fmt.Sprintf("Invalid stack type %T", t))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Equal tests for equality between two JsonPath types.
|
||||||
|
func (p *JsonPath) Equal(o JsonPath) bool {
|
||||||
|
if len(*p) != len(o) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for i, v := range *p {
|
||||||
|
if v != o[i] {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *JsonPath) HasPrefix(o JsonPath) bool {
|
||||||
|
for i, v := range o {
|
||||||
|
if v != (*p)[i] {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
61
vendor/github.com/exponent-io/jsonpath/pathaction.go
generated
vendored
Normal file
61
vendor/github.com/exponent-io/jsonpath/pathaction.go
generated
vendored
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
package jsonpath
|
||||||
|
|
||||||
|
// pathNode is used to construct a trie of paths to be matched
|
||||||
|
type pathNode struct {
|
||||||
|
matchOn interface{} // string, or integer
|
||||||
|
childNodes []pathNode
|
||||||
|
action DecodeAction
|
||||||
|
}
|
||||||
|
|
||||||
|
// match climbs the trie to find a node that matches the given JSON path.
|
||||||
|
func (n *pathNode) match(path JsonPath) *pathNode {
|
||||||
|
var node *pathNode = n
|
||||||
|
for _, ps := range path {
|
||||||
|
found := false
|
||||||
|
for i, n := range node.childNodes {
|
||||||
|
if n.matchOn == ps {
|
||||||
|
node = &node.childNodes[i]
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
} else if _, ok := ps.(int); ok && n.matchOn == AnyIndex {
|
||||||
|
node = &node.childNodes[i]
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return node
|
||||||
|
}
|
||||||
|
|
||||||
|
// PathActions represents a collection of DecodeAction functions that should be called at certain path positions
|
||||||
|
// when scanning the JSON stream. PathActions can be created once and used many times in one or more JSON streams.
|
||||||
|
type PathActions struct {
|
||||||
|
node pathNode
|
||||||
|
}
|
||||||
|
|
||||||
|
// DecodeAction handlers are called by the Decoder when scanning objects. See PathActions.Add for more detail.
|
||||||
|
type DecodeAction func(d *Decoder) error
|
||||||
|
|
||||||
|
// Add specifies an action to call on the Decoder when the specified path is encountered.
|
||||||
|
func (je *PathActions) Add(action DecodeAction, path ...interface{}) {
|
||||||
|
|
||||||
|
var node *pathNode = &je.node
|
||||||
|
for _, ps := range path {
|
||||||
|
found := false
|
||||||
|
for i, n := range node.childNodes {
|
||||||
|
if n.matchOn == ps {
|
||||||
|
node = &node.childNodes[i]
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
node.childNodes = append(node.childNodes, pathNode{matchOn: ps})
|
||||||
|
node = &node.childNodes[len(node.childNodes)-1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
node.action = action
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user