Categorygithub.com/chanced/jsonpointer
modulepackage
0.0.5
Repository: https://github.com/chanced/jsonpointer.git
Documentation: pkg.go.dev

# README

jsonpointer - an RFC 6901 implementation for Go

GoDoc

Package jsonpointer provides the ability to resolve, assign, and delete values of any type, including raw JSON, by JSON Pointers.

Install

go get github.com/chanced/jsonpointer

Usage

General

package main

import (
    "log"
    "encoding/json"
    "github.com/chanced/jsonpointer"
)

type Nested struct {
    Str string
}

type Root struct {
    Nested Nested
}

func main() {

    r := Root{ Nested: Nested{ Str: "nested str" }}

    // jsonpointer.Pointer is a string type so if you have a properly
    // formatted json pointer then you can simply convert it:
    //  ptr := jsonpointer.Pointer(myPointer)
    //  err := ptr.Validate()

    // Note: jsonpointer.New encodes each token's value.
    // "/" encodes to "~1" and "~" encodes to "~0" in compliance with RFC 6901.

    ptr := jsonpointer.New("nested", "str")

    // Resolve

    var s string
    err := jsonpointer.Resolve(r, ptr, &s)
    if err != nil {
        log.Fatal(err)
    }
    log.Println(s) // outputs "nested str"

    // Assign

    err = jsonpointer.Assign(&r, ptr, "new value")
    if err != nil {
        log.Fatal(err)
    }
    log.Println(r.Nested.Str) // outputs "new value"


    // Delete

    err = jsonpointer.Delete(&r, ptr)
    if err != nil {
        log.Fatal(err)
    }
    log.Println(r.Nested.Str) // outputs ""


    // jsonpointer can also Resolve, Assign, and Delete JSON in []byte format.
    // This includes field values, such as those of type json.RawMessage.

    r.Nested.Str = "str val"

    b, err := json.Marshal(r)
    if err != nil {
        log.Fatal(err)
    }

    err = jsonpointer.Resolve(b, ptr, &s)
    if err != nil {
        log.Fatal(err)
    }
    log.Println(s) // outputs "str val"
}

Interfaces

Package jsonpointer provides 3 interfaces: Assigner, Resolver, and Deleter. Regardless of the operation, if Resolver is implemented, ResolvePointer will be called. ResolvePointer should not have side effects. If resolving for an assignment, utilize the pointer to infer which type should be assigned.

AssignByPointer is invoked on the way back from the leaf. DeleteByPointer is invoked after resolving the current token.

All three methods are passed a pointer to the jsonpointer.Pointer so that it can be modified. If you do not modify it, jsonpointer will assume the current token was addressed and continue on.

If you wish to only handle some cases with the interfaces, return jsonpointer.YieldOperation to have the jsonpointer package resolve, assign, or delete as if the type did not implement the interface. Note that doing so results in changes to ptr being dismissed.

Pointer methods

All methods return new values rather than modifying the pointer itself. If you wish to modify the pointer in one of the interface methods, you will need to reassign it: *ptr = newPtrVal

func (mt MyType) ResolvePointer(ptr *jsonpointer.Pointer, op Operation) (interface{}, error) {
    next, t, ok := ptr.Next()
    if !ok {
        // this will only occur if the ptr is a root token in this circumstance
        return mt
    }
    if op == jsonpointer.Assigning && t == "someInterface" {
        // maybe you need to know what comes after someInterface to
        // determine what implementation of someInterface to assign
        t, _ = next.NextToken()

        switch t {
        case "someIdentifier":
            // you could modify ptr if you felt so inclined: *ptr = next
            // but it is not needed in this scenario.
            return SomeImplementation{}, nil
        }
    }
    // otherwise hand resolution back over to jsonpointer
    return nil, jsonpointer.YieldOperation
}

Errors

All errors returned from Resolve, Assign, and Delete will implement Error. A convenience function AsError exists to help extract out the details.

Depending on the cause, the error could also be KeyError, IndexError, FieldError with additional details. All have corresponding As{Error} functions.

Finally, all errors have associated Err instances that are wrapped, such as ErrMalformedToken, ErrInvalidKeyType, and so on.

See errors.go for further details on errors.

Contributions & Issues

Contributions are always welcome. If you run into an issue, please open a issue on github. If you would like to submit a change, feel free to open up a pull request.

Note on Performance

This package is reflect heavy. While it employs the same caching mechanics as encoding/json to help alleviate some of the lookup costs, there will always be a performance hit with reflection.

There are probably plenty of ways to improve performance of the package. Improvements or criticisms are always welcome.

With regards to raw JSON, json.Marshal and json.Unmarshal are utilized. Ideally, in the future, that will change and the package will incoroprate the encoding/decoding logic from encoding/json directly, thus skipping the need to run through unneccesary logic.

Alternative JSON Pointer Packages for Go

License

Apache 2.0

# Functions

No description provided by the author
AsIndexError returns err as a IndexError, if possible.
AsKeyError returns err as a ValueError, if possible.
Assign performs an assignment of value to the target dst specified by the JSON Pointer ptr.
AsValueError returns err as a ValueError, if possible.
Decode decodes a JSON Pointer token by replacing each encoded slash ("~1") with '/' (%x2F) and each encoded tilde ("~0") with '~' (%x7E).
Delete deletes the value at the given JSON pointer from src.
Encode encodes a string to a token of a JSON Pointer by replacing each '~' (%x7E) with "~0" and '/' (%x2F) with "~1".
Deprecated: use Parse instead.
No description provided by the author
No description provided by the author
New encodes and returns the token + tokens into a JSONPointer.
NewFromStrings encodes and returns the tokens into a JSONPointer.
Parse accepts a string, trims any leading '#' and returns str as a Pointer as well as any validation errors.
Resolve performs resolution on src by traversing the path of the JSON Pointer and assigning the value to dst.

# Constants

Assigning is the operation for assigning by a JSON pointer.
Deleting is the operation for deleting by a JSON pointer.
Resolving is the operation for resolving a JSON pointer.
Root is a top-level JSONPointer, indicated by "/".

# Variables

ErrInvalidKeyType indicates the key type is not supported.
No description provided by the author
ErrMalformedIndex indicates a syntax error in the index or a slice or an array.
ErrMalformedStart is an ErrMalformedToken that is returned when the JSON Pointer is not empty or does not start with a "/".
ErrMalformedToken is returned when a JSONPointer token is malformed.
ErrNilInterface is returned when assigning and a nil interface is reached.
ErrNonPointer indicates a non-pointer value was passed to Assign.
ErrNotAssignable indicates the type of the value is not assignable to the provided path.
ErrNotFound indicates a JSONPointer is not reachable from the root object (e.g.
ErrOutOfRange indicates an index is out of range for an array or slice .
ErrUnexportedField indicates the given path is not reachable due to being an unexported field.
ErrUnreachable indicates a reference is not reachable.
YieldOperation returns resolution back to jsonpointer.

# Interfaces

Assigner is the interface implemented by types which can assign values via JSON Pointers.
Deleter is an interface that is implemented by any type which can delete a value by JSON pointer.
Error is a base error type returned from Resolve, Assign, and Delete.
FieldError indicates an error occurred with regards to a field of a struct.
IndexError indicates an error occurred with regards to an index of a slice or array.
KeyError indicates an error occurred with regards to the key of a map or slice.
Resolver is the interface that is implemented by types which can resolve json pointers.
No description provided by the author

# Type aliases

Alias for Pointer Deprecated in favor of Pointer.
Operation is the type of operation being performed.
A Pointer is a Unicode string containing a sequence of zero or more reference tokens, each prefixed by a '/' character.
Token is a segment of a JSON Pointer, divided by '/' (%x2F).
Tokens is a slice of Tokens.