Documentation ¶
Overview ¶
Package jsonpointer provides the ability to resolve, assign, and delete values of any type, including raw JSON, by [JSON Pointers](https://datatracker.ietf.org/doc/html/rfc6901).
Index ¶
- Variables
- func Assign(dst interface{}, ptr Pointer, value interface{}) error
- func Decode(token string) string
- func Delete(src interface{}, ptr Pointer) error
- func Encode(token string) string
- func IsKeyError(err error) bool
- func IsValueError(err error) bool
- func Resolve(src interface{}, ptr Pointer, dst interface{}) error
- type Assigner
- type Deleter
- type Error
- type FieldError
- type IndexError
- type JSONPointer
- type KeyError
- type Operation
- type Pointer
- func (p Pointer) Append(token Token) Pointer
- func (p Pointer) AppendString(token string) Pointer
- func (p Pointer) IsRoot() bool
- func (p Pointer) LastToken() (Token, bool)
- func (p Pointer) Next() (Pointer, Token, bool)
- func (p Pointer) NextPointer() (Pointer, bool)
- func (p Pointer) NextToken() (Token, bool)
- func (p Pointer) Pop() (Pointer, Token, bool)
- func (p Pointer) Prepend(token Token) Pointer
- func (p Pointer) PrependString(token string) Pointer
- func (p Pointer) String() string
- func (p Pointer) Tokens() []string
- func (p Pointer) Validate() (err error)
- type Resolver
- type Token
- type Tokens
- type ValueError
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrMalformedToken is returned when a JSONPointer token is malformed. // // This error is returned by JSONPointer.Validate() which is called by // Resolve, Assign, and Delete. // ErrMalformedToken = errors.New(`jsonpointer: fragment is malformed`) // ErrMalformedStart is an ErrMalformedToken that is returned when the JSON // Pointer is not empty or does not start with a "/". ErrMalformedStart = fmt.Errorf(`%w; pointer must be an empty string or start with "/"`, ErrMalformedToken) ErrMalformedEncoding = fmt.Errorf("%w; '~' must be encoded as ~0", ErrMalformedToken) // ErrNonPointer indicates a non-pointer value was passed to Assign. // ErrNonPointer = errors.New("jsonpointer: dst must be a pointer") // ErrUnexportedField indicates the given path is not reachable due to being // an unexported field. // ErrUnexportedField = errors.New("jsonpointer: unexported field") // ErrInvalidKeyType indicates the key type is not supported. // // Custom key types must implement encoding.TextUnmarshaler // ErrInvalidKeyType = errors.New("jsonpointer: invalid key type") // ErrNotAssignable indicates the type of the value is not assignable to the // provided path. // ErrNotAssignable = errors.New("jsonpointer: invalid value type") // ErrNotFound indicates a JSONPointer is not reachable from the root object // (e.g. a nil pointer, missing map key). // ErrNotFound = errors.New(`jsonpointer: value not found`) // ErrOutOfRange indicates an index is out of range for an array or slice // ErrOutOfRange = errors.New("jsonpointer: index out of range") // ErrUnreachable indicates a reference is not reachable. This occurs when // resolving and a primitive (string, number, or bool) leaf node is reached // and the reference is not empty. // ErrUnreachable = fmt.Errorf("%w due to being unreachable", ErrNotFound) // ErrNilInterface is returned when assigning and a nil interface is // reached. // // To solve this, the node containing the interface should implement // jsonpoint.Resolver and return a non-nil implemention of the interface. // ErrNilInterface = errors.New("jsonpointer: can not assign due to nil interface") // ErrMalformedIndex indicates a syntax error in the index or a slice or an array. ErrMalformedIndex = errors.New("jsonpointer: malformed slice or array index") )
var YieldOperation = errors.New("yield resolution to jsonpointer")
YieldOperation returns resolution back to jsonpointer. This error can be utilized within methods satisfying Resolver (ResolveJSONPointer), Assigner (AssignByJSONPointer), and Deleter (DeleteByJSONPointer) as an escape hatch.
The intent is is that there may only be certain fields that your application would like to manually resolve. For the rest, you'd return YieldOperation as the error.
Functions ¶
func Assign ¶
Assign performs an assignment of value to the target dst specified by the JSON Pointer ptr. Assign traverses dst recursively, resolving the path of the JSON Pointer. If a type in the path implements Resolver, it will attempt to resolve by invoking ResolveJSONPointer on that value. If ResolveJSONPointer returns YieldOperation or if the value does not implement ResolveJSONPointer, encoding/json naming conventions are utilized to resolve the path.
If a type in the path implements Assigner, AssignByJSONPointer will be called with the updated value pertinent to that path.
Example ¶
package main import ( "encoding/json" "fmt" "github.com/chanced/jsonpointer" ) func main() { type Bar struct { Baz string `json:"baz"` } type Foo struct { Bar Bar `json:"bar"` } var foo Foo jsonpointer.Assign(&foo, "/bar/baz", "qux") fmt.Println(foo.Bar.Baz) // Assigning JSON by JSONPointer foo.Bar.Baz = "quux" b, _ := json.Marshal(foo) jsonpointer.Assign(&b, "/bar/baz", "corge") fmt.Println(string(b)) }
Output: qux {"bar":{"baz":"corge"}}
func Decode ¶
Decode decodes a JSON Pointer token by replacing each encoded slash ("~1") with '/' (%x2F) and each encoded tilde ("~0") with '~' (%x7E).
func Delete ¶
Delete deletes the value at the given JSON pointer from src.
If any part of the path is unreachable, the Delete function is considered a success as the value is not present to delete.
Example ¶
package main import ( "encoding/json" "fmt" "github.com/chanced/jsonpointer" ) func main() { type Bar struct { Baz string `json:"baz,omitempty"` } type Foo struct { Bar Bar `json:"bar"` } foo := Foo{Bar{Baz: "qux"}} jsonpointer.Delete(foo, "/bar/baz") fmt.Printf("foo.Bar.Baz: %v\n", foo.Bar.Baz) // Deleting JSON by JSONPointer foo.Bar.Baz = "quux" b, _ := json.Marshal(foo) jsonpointer.Delete(&b, "/bar/baz") fmt.Println(string(b)) }
Output: foo.Bar.Baz: qux {"bar":{}}
func Encode ¶
Encode encodes a string to a token of a JSON Pointer by replacing each '~' (%x7E) with "~0" and '/' (%x2F) with "~1".
func IsKeyError ¶
func IsValueError ¶
func Resolve ¶
Resolve performs resolution on src by traversing the path of the JSON Pointer and assigning the value to dst. If the path can not be reached, an error is returned.
Example ¶
package main import ( "encoding/json" "fmt" "github.com/chanced/jsonpointer" ) func main() { type Bar struct { Baz string `json:"baz"` } type Foo struct { Bar Bar `json:"bar,omitempty"` } foo := Foo{Bar{Baz: "qux"}} var s string jsonpointer.Resolve(foo, "/bar/baz", &s) fmt.Println(s) // Resolving JSON by JSONPointer b, _ := json.Marshal(foo) jsonpointer.Resolve(b, "/bar/baz", &s) fmt.Println(s) }
Output: qux qux
Types ¶
type Assigner ¶
Assigner is the interface implemented by types which can assign values via JSON Pointers. The input can be assumed to be a valid JSON Pointer and the value to assign.
AssignByJSONPointer is called after the value has been resolved. If custom resolution is needed, the type should also implement Resolver.
type Deleter ¶
Deleter is an interface that is implemented by any type which can delete a value by JSON pointer.
type Error ¶
type Error interface { error JSONPointer() Pointer CurrentJSONPointer() Pointer Token() (Token, bool) Operation() Operation Unwrap() error Type() reflect.Type }
Error is a base error type returned from Resolve, Assign, and Delete.
type FieldError ¶
type FieldError interface { Error Field() reflect.StructField }
FieldError indicates an error occurred with regards to a field of a struct.
type IndexError ¶
IndexError indicates an error occurred with regards to an index of a slice or array. The error may be wrapped in an Error if it is returned from an operation on a JSON Pointer.
err.Index() will return -1 if:
- the source or destination is an array, token is equal to "-", and the array does not have a zero value.
- the token can not be parsed as an int
func AsIndexError ¶
func AsIndexError(err error) (IndexError, bool)
AsIndexError returns err as a IndexError, if possible. It does so by calling errors.As, returning a IndexError and true if successful. If unsuccessful, nil and false is returned.
type KeyError ¶
KeyError indicates an error occurred with regards to the key of a map or slice.
func AsKeyError ¶
AsKeyError returns err as a ValueError, if possible. It does so by calling errors.As, returning a KeyError and true if successful. If unsuccessful, nil and false is returned.
type Operation ¶
type Operation uint8
Operation is the type of operation being performed.
func (Operation) IsAssigning ¶
IsAssigning returns true if the operation is an assignment.
func (Operation) IsDeleting ¶
IsDeleting returns true if the operation is a deletion.
func (Operation) IsResolving ¶
IsResolving returns true if the operation is a resolution.
type Pointer ¶ added in v0.0.3
type Pointer string
A Pointer is a Unicode string containing a sequence of zero or more reference tokens, each prefixed by a '/' character.
See [rfc 6901 for more information](https://datatracker.ietf.org/doc/html/rfc6901).
const ( // Root is a top-level JSONPointer, indicated by "/". Root Pointer = "" )
func New ¶
New encodes and returns the token + tokens into a JSONPointer.
Examples:
jsonpointer.New("foo", "bar") => "/foo/bar" jsonpointer.New("/foo/bar") => "/~1foo~1bar" jsonpointer.New() => "/" jsonpointer.New("") => "/" jsonpointer.New("/") => "/~1" jsonpointer.New("~") => "/~0"
Example ¶
package main import ( "fmt" "github.com/chanced/jsonpointer" ) func main() { ptr := jsonpointer.New("foo", "bar") // => "/foo/bar" fmt.Println(`"` + ptr + `"`) ptr = jsonpointer.New("foo/bar") // => "/foo~1bar" fmt.Println(`"` + ptr + `"`) ptr = jsonpointer.New() // => "" fmt.Println(`"` + ptr + `"`) ptr = jsonpointer.New("") // => "/" fmt.Println(`"` + ptr + `"`) ptr = jsonpointer.New("/") // => "/~1" fmt.Println(`"` + ptr + `"`) ptr = jsonpointer.New("~") // => "/~0" fmt.Println(`"` + ptr + `"`) ptr = jsonpointer.New("#/foo/bar") // => "/#~1foo~1bar" fmt.Println(`"` + ptr + `"`) }
Output: "/foo/bar" "/foo~1bar" "" "/" "/~1" "/~0" "/#~1foo~1bar"
func NewFromStrings ¶
NewFromStrings encodes and returns the tokens into a JSONPointer.
Examples:
jsonpointer.NewFromStrings([]string{"foo", "bar", "baz"}) => "/foo/bar/baz"
func Parse ¶ added in v0.0.5
Parse accepts a string, trims any leading '#' and returns str as a Pointer as well as any validation errors.
func (Pointer) Append ¶ added in v0.0.3
Append appends token to the end of reference p and returns the new JSONPointer.
Note: token is not encoded. Use p.AppendString to encode and append the token.
func (Pointer) AppendString ¶ added in v0.0.3
AppendString encodes and appends token to the value of p and returns the new JSONPointer.
func (Pointer) Next ¶ added in v0.0.3
Next splits the JSONPointer at the first slash and returns the token and the remaining JSONPointer.
func (Pointer) NextPointer ¶ added in v0.0.3
func (Pointer) NextToken ¶ added in v0.0.3
NextToken splits the JSONPointer at the first slash and returns the token.
func (Pointer) Prepend ¶ added in v0.0.3
Preppend prepends token to the beginning of the value of p and returns the resulting JSONPointer.
Note: token is not encoded. Use p.PrependString to encode and prepend the token.
func (Pointer) PrependString ¶ added in v0.0.3
PrependString encodes and prepends token to the value of p and returns the new JSONPointer.
type Resolver ¶
Resolver is the interface that is implemented by types which can resolve json pointers. The method is expected not to have side effects to the source.
type Token ¶
type Token string
Token is a segment of a JSON Pointer, divided by '/' (%x2F).
func (Token) Index ¶
Index parses t for an index value. If t can be parsed as an int, is equal to or greater than 0 and less than or equal to next then the value is returned. If t is equal to "-" then next is returned. If neither condition is true, -1 and an IndexError is returned.
next must be greater than or equal to 0.
func (Token) Int ¶
Int attempts to parse t as an int. If t can be parsed as an int then the value is returned. If t can not be parsed as an int then an error is returned.
type Tokens ¶
type Tokens []Token
Tokens is a slice of Tokens.
type ValueError ¶
func AsValueError ¶
func AsValueError(err error) (ValueError, bool)
AsValueError returns err as a ValueError, if possible.