Documentation
¶
Overview ¶
jsonpointer follows the IETF RFC 6901 spec for dereferenceing arbitrary values from JSON data structures. See http://tools.ietf.org/html/rfc6901 for the JSON Pointer spec.
Note that unless otherwise stated code examples are evaluated against the example data structure from http://tools.ietf.org/html/rfc6901#section-5 :
{
"foo": ["bar", "baz"],
"": 0,
"a/b": 1,
"c%d": 2,
"e^f": 3,
"g|h": 4,
"i\\j": 5,
"k\"l": 6,
" ": 7,
"m~n": 8
}
License ¶
This package is licensed under the ISC License, a modernized MIT/BSD equivelent license, see: https://en.wikipedia.org/wiki/ISC_license or the LICENSE file in the source directory for further details.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type ArrayIndexOutOfBounds ¶
type ArrayIndexOutOfBounds struct {
// contains filtered or unexported fields
}
ArrayIndexOutOfBounds errors indicate that a valid, numeric index is beyond the bounds of the array (slice) being dereferenced.
func (ArrayIndexOutOfBounds) Error ¶
func (e ArrayIndexOutOfBounds) Error() string
Error Returns a informative error message as a string
Example ¶
Calling Get with a pointer value that dereferences an array index beyond it's bounds will return an ArrayIndexOutOfBounds error. When calling set this also applies except that if the index is equal to the array length it is considered valid and performs ano": ["bar", "baz"], append. See above for the JSON data being evaluated.
pointer, _ := NewJSONPointerFromString("/foo/2")
_, err := pointer.Get(ExampleJson, -1)
fmt.Println(err)
Output: array index 2 is beyond the array bounds.
type BadEscapeSequence ¶
type BadEscapeSequence struct {
// contains filtered or unexported fields
}
BadEscapeSequence errors indicate that the provided JSON pointer string contained an invalid escape sequence. Currenly the only allowed escape sequences are "~0" which escapes "~" and "~1" which escapes "/". The '~' character must not be followed by any character other than '0' or '1'.
func (BadEscapeSequence) Error ¶
func (e BadEscapeSequence) Error() string
Error Returns a informative error message as a string
Example ¶
Providing a string with an invalid escape sequence to NewJSONPointer will return a BadEscapeSequence error. See above for the JSON data being evaluated.
_, err := NewJSONPointerFromString("/foo/~2")
fmt.Print(err)
Output: the escape sequence "~2" found in the JSON pointer "/foo/~2" is invalid
type InvalidArrayIndex ¶
type InvalidArrayIndex struct {
// contains filtered or unexported fields
}
InvalidArrayIndex errors indicate that the JSONPointer could not dereference an array using the given token (I.E. the token was not numberic, or '-' in the case of Set() calls.)
func (InvalidArrayIndex) Error ¶
func (e InvalidArrayIndex) Error() string
Error Returns a informative error message as a string
Example ¶
Calling Get or Set with a pointer value that dereferences an array index where the token is non-numeric will return an InvalidArrayIndex error. When calling Set this also applies except that the token "-" is evaluated to the length of the array (and thus performs an append.) See above for the JSON data being evaluated.
pointer, _ := NewJSONPointerFromString("/foo/!")
_, err := pointer.Get(ExampleJson, -1)
fmt.Println(err)
Output: cannot index an array by the value "!"
type JSONPointer ¶
type JSONPointer struct {
// contains filtered or unexported fields
}
JSONPointer follows IETF RFC 6901 for using a string value to test, access and/or modify a JSON data structure. The zero value of a JSONPointer would be have zero tokens and a string representation of "" (the empty string.) This zero value is functionally usable and targets the root document itself.
func NewJSONPointerFromString ¶
func NewJSONPointerFromString(pointer string) (*JSONPointer, error)
NewJSONPointer attempts to create a new JSONPointer instance from it's string representation according to IETF RFC 6901 rules. The primary use case for this would be to query a JSON data structure.
Example ¶
This example represents the example tests outlined in setion 5 of IETF RFC 6901 (http://tools.ietf.org/html/rfc6901#section-5) which all pass:
pointer, _ := NewJSONPointerFromString("")
value, _ := pointer.Get(ExampleJson, -1)
fmt.Println(reflect.DeepEqual(value, ExampleJson))
pointer, _ = NewJSONPointerFromString("/foo")
value, _ = pointer.Get(ExampleJson, -1)
fmt.Println(reflect.DeepEqual(value, ExampleJson["foo"]))
pointer, _ = NewJSONPointerFromString("/foo/0")
value, _ = pointer.Get(ExampleJson, -1)
fmt.Println(reflect.DeepEqual(value, "bar"))
pointer, _ = NewJSONPointerFromString("/")
value, _ = pointer.Get(ExampleJson, -1)
fmt.Println(value.(float64) == float64(0))
pointer, _ = NewJSONPointerFromString("/a~1b")
value, _ = pointer.Get(ExampleJson, -1)
fmt.Println(value.(float64) == float64(1))
pointer, _ = NewJSONPointerFromString("/c%d")
value, _ = pointer.Get(ExampleJson, -1)
fmt.Println(value.(float64) == float64(2))
pointer, _ = NewJSONPointerFromString("/e^f")
value, _ = pointer.Get(ExampleJson, -1)
fmt.Println(value.(float64) == float64(3))
pointer, _ = NewJSONPointerFromString("/g|h")
value, _ = pointer.Get(ExampleJson, -1)
fmt.Println(value.(float64) == float64(4))
pointer, _ = NewJSONPointerFromString("/i\\j")
value, _ = pointer.Get(ExampleJson, -1)
fmt.Println(value.(float64) == float64(5))
pointer, _ = NewJSONPointerFromString("/k\"l")
value, _ = pointer.Get(ExampleJson, -1)
fmt.Println(value.(float64) == float64(6))
pointer, _ = NewJSONPointerFromString("/ ")
value, _ = pointer.Get(ExampleJson, -1)
fmt.Println(value.(float64) == float64(7))
pointer, _ = NewJSONPointerFromString("/m~0n")
value, _ = pointer.Get(ExampleJson, -1)
fmt.Println(value.(float64) == float64(8))
Output: true true true true true true true true true true true true
func NewJSONPointerFromTokens ¶
func NewJSONPointerFromTokens(tokens *[]string) *JSONPointer
NewJSONPointerFromTokens attempts to create a new JSONPointer instance from a slice of strings representing it's individual tokens. The primary use case for this would be to convert a sequence of tokens into an IETF RFC 6901 compliant string representation.
Example ¶
This example represents the example tests outlined in setion 5 of IETF RFC 6901 as they would be implemented with NewJSONPointerFromTokens for comparison with the other constructor methods. Note that this method has no error conditions providing a nicer (or at least more chainable) API.
value, _ := NewJSONPointerFromTokens(&[]string{}).Get(ExampleJson, -1)
fmt.Println(reflect.DeepEqual(value, ExampleJson))
value, _ = NewJSONPointerFromTokens(&[]string{"foo"}).Get(ExampleJson, -1)
fmt.Println(reflect.DeepEqual(value, ExampleJson["foo"]))
value, _ = NewJSONPointerFromTokens(&[]string{"foo", "0"}).Get(
ExampleJson,
-1)
fmt.Println(reflect.DeepEqual(value, "bar"))
value, _ = NewJSONPointerFromTokens(&[]string{""}).Get(ExampleJson, -1)
fmt.Println(value.(float64) == float64(0))
value, _ = NewJSONPointerFromTokens(&[]string{"a/b"}).Get(ExampleJson, -1)
fmt.Println(value.(float64) == float64(1))
value, _ = NewJSONPointerFromTokens(&[]string{"c%d"}).Get(ExampleJson, -1)
fmt.Println(value.(float64) == float64(2))
value, _ = NewJSONPointerFromTokens(&[]string{"e^f"}).Get(ExampleJson, -1)
fmt.Println(value.(float64) == float64(3))
value, _ = NewJSONPointerFromTokens(&[]string{"g|h"}).Get(ExampleJson, -1)
fmt.Println(value.(float64) == float64(4))
value, _ = NewJSONPointerFromTokens(&[]string{"i\\j"}).Get(ExampleJson, -1)
fmt.Println(value.(float64) == float64(5))
value, _ = NewJSONPointerFromTokens(&[]string{"k\"l"}).Get(ExampleJson, -1)
fmt.Println(value.(float64) == float64(6))
value, _ = NewJSONPointerFromTokens(&[]string{" "}).Get(ExampleJson, -1)
fmt.Println(value.(float64) == float64(7))
value, _ = NewJSONPointerFromTokens(&[]string{"m~n"}).Get(ExampleJson, -1)
fmt.Println(value.(float64) == float64(8))
Output: true true true true true true true true true true true true
func NewJSONPointerFromURIFragment ¶
func NewJSONPointerFromURIFragment(fragment string) (*JSONPointer, error)
NewJSONPointerFromURIFragment works just like NewJSONPointerFromString except that it will unescape URL escape sequences (like %20 for a space). A leading '#' fragment root token is optional in light of the fact that it is stripped from net/url standard library Url struct "Fragment" fields.
Example ¶
This example represents the example tests outlined in setion 6 of IETF RFC 6901 (http://tools.ietf.org/html/rfc6901#section-6) which all pass.
pointer, _ := NewJSONPointerFromURIFragment("#")
value, _ := pointer.Get(ExampleJson, -1)
fmt.Println(reflect.DeepEqual(value, ExampleJson))
pointer, _ = NewJSONPointerFromURIFragment("#/foo")
value, _ = pointer.Get(ExampleJson, -1)
fmt.Println(reflect.DeepEqual(value, ExampleJson["foo"]))
pointer, _ = NewJSONPointerFromURIFragment("#/foo/0")
value, _ = pointer.Get(ExampleJson, -1)
fmt.Println(reflect.DeepEqual(value, "bar"))
pointer, _ = NewJSONPointerFromURIFragment("#/")
value, _ = pointer.Get(ExampleJson, -1)
fmt.Println(value.(float64) == float64(0))
pointer, _ = NewJSONPointerFromURIFragment("#/a~1b")
value, _ = pointer.Get(ExampleJson, -1)
fmt.Println(value.(float64) == float64(1))
pointer, _ = NewJSONPointerFromURIFragment("#/c%25d")
value, _ = pointer.Get(ExampleJson, -1)
fmt.Println(value.(float64) == float64(2))
pointer, _ = NewJSONPointerFromURIFragment("#/e%5Ef")
value, _ = pointer.Get(ExampleJson, -1)
fmt.Println(value.(float64) == float64(3))
pointer, _ = NewJSONPointerFromURIFragment("#/g%7Ch")
value, _ = pointer.Get(ExampleJson, -1)
fmt.Println(value.(float64) == float64(4))
pointer, _ = NewJSONPointerFromURIFragment("#/i%5Cj")
value, _ = pointer.Get(ExampleJson, -1)
fmt.Println(value.(float64) == float64(5))
pointer, _ = NewJSONPointerFromURIFragment("#/k%22l")
value, _ = pointer.Get(ExampleJson, -1)
fmt.Println(value.(float64) == float64(6))
pointer, _ = NewJSONPointerFromURIFragment("#/%20")
value, _ = pointer.Get(ExampleJson, -1)
fmt.Println(value.(float64) == float64(7))
pointer, _ = NewJSONPointerFromURIFragment("#/m~0n")
value, _ = pointer.Get(ExampleJson, -1)
fmt.Println(value.(float64) == float64(8))
Output: true true true true true true true true true true true true
func (*JSONPointer) Depth ¶
func (p *JSONPointer) Depth() int
Depth returns the number of tokens in a JSON Pointer.
Example ¶
Note that the first example is a JSON pointer to the root document, while the second example references the empty string key ("") directly under the root document.
pointer, _ := NewJSONPointerFromString("")
fmt.Println(pointer.Depth())
pointer, _ = NewJSONPointerFromString("/")
fmt.Println(pointer.Depth())
pointer, _ = NewJSONPointerFromString("/foo")
fmt.Println(pointer.Depth())
pointer, _ = NewJSONPointerFromString("/foo/bar/baz")
fmt.Println(pointer.Depth())
Output: 0 1 1 3
func (*JSONPointer) Get ¶
func (p *JSONPointer) Get(data interface{}, depth int) (interface{}, error)
Get returns the value from the provided JSON data structure identified by this JSONPointer. The `depth` argument can be used to limit the number of tokens that will be evaluated into the structure, a value of -1 will evaluate the entire token chain, a value of 0 will return the provided data structure itself.
Example ¶
pointer, err := NewJSONPointerFromString("/foo")
value, err := pointer.Get(ExampleJson, -1)
fmt.Println(value, err)
pointer, err = NewJSONPointerFromString("/foo/0")
value, err = pointer.Get(ExampleJson, -1)
fmt.Println(value, err)
pointer, err = NewJSONPointerFromString("/foo/0/boom")
value, err = pointer.Get(ExampleJson, -1)
fmt.Println(value, err)
pointer, err = NewJSONPointerFromString("/foo/0/boom")
value, err = pointer.Get(ExampleJson, 2)
fmt.Println(value, err)
Output: [bar baz] <nil> bar <nil> <nil> cannot index primitave value "bar" bar <nil>
func (*JSONPointer) Set ¶
func (p *JSONPointer) Set(data interface{}, value interface{}, depth int) (interface{}, error)
Set changes the value from the provided JSON data structure identified by this JSONPointer. The `depth` argument can be used to limit the number of tokens that will be evaluated into the structure, a value of -1 will evaluate the entire token chain, a value of 0 will return the provided data structure itself. Set always returns the provided data structure, this way if an append occurs on the root level document you will receive the updated array which may have been reallocated by Go.
Example ¶
// Construct the same JSON data structure used by other examples, but since
// it will be modified we create a new instance that won't effect other
// tests.
var Json map[string]interface{}
_ = json.Unmarshal([]byte(JSONBytes), &Json)
pointer, _ := NewJSONPointerFromString("/foo/2")
value, _ := pointer.Set(Json, "qux", -1)
value, err := pointer.Get(value, 1)
fmt.Println(value, err)
// Lets see what happens with an array index greater than the length
pointer, _ = NewJSONPointerFromString("/foo/4")
_, err = pointer.Set(Json, "corge", -1)
fmt.Println(err)
// The '-' token is a special token that can only be used for Set operations
// which will always append to the end of an array.
pointer, _ = NewJSONPointerFromString("/foo/-")
_, err = pointer.Set(Json, "corge", -1)
value, _ = pointer.Get(Json, 1)
fmt.Println(value)
// Oops, that's the wrong metastatic variable!
pointer, _ = NewJSONPointerFromString("/foo/3")
_, err = pointer.Set(Json, "quux", -1)
value, _ = pointer.Get(Json, 1)
fmt.Println(value)
pointer, _ = NewJSONPointerFromString("/o@p")
_, _ = pointer.Set(Json, 9, -1)
value, err = pointer.Get(Json, -1)
fmt.Println(value)
// Finally let's engineer a situation where an append must occur on the root
// document to illustrate that in this corner case you will only see the
// changed data if you capture the returned data:
data := make([]interface{}, 2, 2)
data[0], data[1] = "bar", "baz"
pointer, _ = NewJSONPointerFromString("/2")
value, _ = pointer.Set(data, "qux", -1)
fmt.Println(data, value)
Output: [bar baz qux] <nil> array index 4 is beyond the array bounds. [bar baz qux corge] [bar baz qux quux] 9 [bar baz] [bar baz qux]
func (*JSONPointer) String ¶
func (p *JSONPointer) String() string
String returns the unescaped IETF RFC 6901 string representation of this JSON pointer.
Example ¶
One of the likely use cases for constructing JSONPointers from string slices as is done with NewJSONPointerFromTokens would be to construct a valid JSONPointer string for a given property/index path. Here's how to do that:
pointer := NewJSONPointerFromTokens(&[]string{})
fmt.Printf("%q\n", pointer.String())
pointer = NewJSONPointerFromTokens(&[]string{""})
fmt.Printf("%q\n", pointer.String())
pointer = NewJSONPointerFromTokens(&[]string{"foo"})
fmt.Printf("%q\n", pointer.String())
pointer = NewJSONPointerFromTokens(&[]string{"foo", "bar", "baz"})
fmt.Printf("%q\n", pointer.String())
Output: "" "/" "/foo" "/foo/bar/baz"
func (*JSONPointer) Tokens ¶
func (p *JSONPointer) Tokens() []string
Tokens returns the escaped tokens that will be used to dereference a JSON data structure.
Example ¶
Note that the difference between the first and second example is that the first is completely empty, while the second contains one string which happens to be the empty string ("".)
pointer, _ := NewJSONPointerFromString("")
tokens := pointer.Tokens()
fmt.Println(len(tokens), tokens)
pointer, _ = NewJSONPointerFromString("/")
tokens = pointer.Tokens()
fmt.Println(len(tokens), tokens)
pointer, _ = NewJSONPointerFromString("/foo")
tokens = pointer.Tokens()
fmt.Println(len(tokens), tokens)
pointer, _ = NewJSONPointerFromString("/foo/bar/baz")
tokens = pointer.Tokens()
fmt.Println(len(tokens), tokens)
Output: 0 [] 1 [] 1 [foo] 3 [foo bar baz]
type JSONPointerSyntaxError ¶
type JSONPointerSyntaxError struct {
// contains filtered or unexported fields
}
JSONPointerSyntaxError indicates that the provided string representation of a JSON pointer is invalid. To be a valid JSON pointer string it must either: be the empty string (""), or start with a forward slash ("/").
func (JSONPointerSyntaxError) Error ¶
func (e JSONPointerSyntaxError) Error() string
Error Returns a informative error message as a string
Example ¶
Calling NewJSONPointerFromString with a string that neither is the empty string nor starts with a "/" is invalid and will return a JSONPointerSyntaxError
_, err := NewJSONPointerFromString("boom")
fmt.Print(err)
Output: "boom" is not a valid JSON pointer string representation.
type UnindexableValue ¶
type UnindexableValue struct {
// contains filtered or unexported fields
}
UnindexableValue error indicates that the JSONPointer reached a primitave value which cannot be indexed into before running out of tokens to dereference.
func (UnindexableValue) Error ¶
func (e UnindexableValue) Error() string
Error Returns a informative error message as a string
Example ¶
Calling Get or Set with a pointer that dereferences a primitave (null/nil, boolean/bool, number/float64 or string) before exausting all tokens to be evaluated will return a UnindexableValue error. See above for the JSON data being evaluated.
pointer, _ := NewJSONPointerFromString("/foo/0/boom/big")
_, err := pointer.Set(ExampleJson, "badda", -1)
fmt.Println(err)
Output: cannot index primitave value "bar"