jsonpatch

package module
v0.0.0-...-829ba14 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 13, 2021 License: MIT Imports: 6 Imported by: 0

README

json-patch

Go Reference Go Report Card

This is a very modest attempt to bridge the gap between JSON Path and JSON Patch.

Rationale

The JSON Patch ( RFC-6902 ) way of patching uses JSON Pointer ( RFC-6901 ) to refer to specific predetermined spots within a document. While that's great for some kinds of documents, transforming recursively defined data seems outside of its scope. And while the JSON Path concept can be used with recursive data, there don't seem to be any off-the-shelf tools for patching data using its paths.

There's no perfect standard for JSON Paths. This uses PaesslerAG's. There are others.

Differences b/t the RFC and this lib.

  • JSON Paths affect multiple values; so each operation affects multiple nodes.
  • RFC compliant error handling hasn't been evaluated.
  • Array handling hasn't been explored deeply.
  • The operation "test" in the RFC requires a value, here it does not. Also, "test" here supports arrays of recursive "patches" and "subpatches", both of which are processed should the test succeed. The "patches" applies its operations to the current document. The "subpatches" applies its operations to each object matched by the test.
  • Defines a "reason" key as a way to add comments to patch files.
  • Paths can (optionally) be specified as a pair of values -- a parent path targeting one or more json objects, and a child field string within each matching object. This is required for some case where paths use filters ( https://github.com/ionous/json-patch/issues/1 )

While it's not necessary to have this gracefully decay into the RFC behavior ( ie. so that it can directly support json patch documents ) that would be cool. ( ex. replace the path pair with a single string value; transform json pointers starting with "/" into their "$" path equivalents; directly support all verbs; correctly handle errors; ... )

It also might be nice to merge the 'test' op's "patches" and "subpatches". Each path could itself could indicate the desired matching behavior. For instance, paths starting with the standard $ could match against the current document, while @ could match against the object matched by the test.

Sample Patch

See https://github.com/ionous/json-patch/tree/main/examples for some example data.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var EscapeHTML = false

EscapeHTML - replace &, >, and < with unicode sequences when copying / comparing strings? ( default for jsonpatch is not )

Functions

func Clone

func Clone(doc interface{}) (ret interface{}, err error)

Clone copies an in-memory json document. ( so we don't accidentally share objects which might later need separate, unique, transformations. )

func CompareValues

func CompareValues(from Cursor, field string, value json.RawMessage) (retMatches, retMismatch int, err error)

CompareValues compares a path against raw json bytes; FIX: it's currently untested. ( This is normally used via patch commands. )

func ExtractValues

func ExtractValues(from Cursor, field string, del bool) (ret []interface{}, err error)

ExtractValues of the named fields within the objects selected by the passed cursor. If del is true it will remove those elements from the document. ( This is normally used via patch commands. )

func InsertValues

func InsertValues(to Cursor, field string, vals []interface{}) (ret int, err error)

InsertValues puts the passed values into the targeted objects; the values are not cloned. The number of source and target values must match; returns the number of successful replications. ( This is normally used via patch commands. )

func Jstr

func Jstr(s string) (ret interface{})

Jstr turns a string into json data ( for writing patches in go. ) FIX: restore the example.

func ReplaceValues

func ReplaceValues(from Cursor, field string, msg json.RawMessage) (ret int, err error)

ReplaceValues adds the passed raw json to the 'field' of objects selected by the passed cursor. ( This is normally used via patch commands. )

Types

type Copy

type Copy struct {
	From Target `json:"from"`
	To   Target `json:"path"`
}

Copy - a Migration - replicates pieces of a document.

func (*Copy) Migrate

func (op *Copy) Migrate(doc interface{}) (ret int, err error)

Migrate runs the copy command.

type Cursor

type Cursor struct {
	// contains filtered or unexported fields
}

Cursor reads (caches) a collection of objects from a json docs.

func (*Cursor) Element

func (c *Cursor) Element(i int) (ret interface{})

Element returns one of the targeted objects.

func (*Cursor) Path

func (c *Cursor) Path() Path

Path that describes the collection of objects targeted by the cursor.

func (*Cursor) Resolve

func (c *Cursor) Resolve() (ret int, err error)

Resolve reads (caches) the objects targeted by a json path and returns the number of matches.

type Migration

type Migration interface {
	Migrate(doc interface{}) (int, error)
}

Migration interface for patching json.

type Move

type Move struct {
	From Target `json:"from"`
	To   Target `json:"path"`
}

Move - a Migration - relocates pieces of a document.

func (*Move) Migrate

func (op *Move) Migrate(doc interface{}) (ret int, err error)

Migrate copies to the new location then removes from the old.

type PatchCommand

type PatchCommand struct {
	Migration // pointer to the command
}

PatchCommand holds a single command for the purpose of de/serializing a migration.

func (*PatchCommand) UnmarshalJSON

func (c *PatchCommand) UnmarshalJSON(data []byte) (err error)

UnmarshalJSON creates concrete implementations of migrations.

type Patches

type Patches []PatchCommand

Patches - a Migration - runs a series of other migrations.

func (Patches) ApplyOverMatches

func (ps Patches) ApplyOverMatches(cs Cursor) (ret int, err error)

ApplyOverMatches runs this series of operations over all objects matched by the passed cursor.

func (Patches) Migrate

func (ps Patches) Migrate(doc interface{}) (ret int, err error)

Migrate runs a list of migrations.

type Path

type Path string

Path provides a JSONPath ready string. See: https://goessner.net/articles/JsonPath/, and https://github.com/PaesslerAG/

func (Path) Select

func (p Path) Select(doc interface{}) Cursor

Select prepares a collection of elements from a json doc pointed to by the path.

func (Path) String

func (p Path) String() string

type Remove

type Remove struct {
	Path Target `json:"path"`
}

Remove - a Migration - deletes pieces of a document.

func (*Remove) Migrate

func (op *Remove) Migrate(doc interface{}) (ret int, err error)

Migrate runs the replace command.

type Replace

type Replace struct {
	Path  Target          `json:"path"`
	Value json.RawMessage `json:"value"`
}

Replace - a Migration - substitutes new values for pieces of a document.

func (*Replace) Migrate

func (op *Replace) Migrate(doc interface{}) (ret int, err error)

Migrate runs the replace command.

type Target

type Target struct {
	Parent   Path   `json:"parent"`
	Field    string `json:"field"`
	FullPath Path   // original path, the join of parent and field.
}

Target a location in a json document with a json path pointing to (one or more) objects, and a field addressing a member of each objects.

func At

func At(parent, field string) Target

At makes a serializable target ( for writing patches in go. ) FIX: restore the example.

func (*Target) UnmarshalJSON

func (c *Target) UnmarshalJSON(data []byte) (err error)

UnmarshalJSON creates concrete implementations of migrations.

type Test

type Test struct {
	Path       Target          `json:"path"`
	Value      json.RawMessage `json:"value,omitempty"`
	Patches    Patches         `json:"patches,omitempty"`
	SubPatches Patches         `json:"subpatches,omitempty"`
}

Test - a Migration - validates pieces of a document, then possibly runs sub matches. Patches are run against the current document, and not specifically things matched by the test. SubPatches are run against all elements matched by the test.

func (*Test) Migrate

func (op *Test) Migrate(doc interface{}) (ret int, err error)

Migrate runs the test command; potentially recursive.

type UnknownKey

type UnknownKey struct {
	// contains filtered or unexported fields
}

UnknownKey replaces jsonpath's string error for key not found.

func (UnknownKey) Error

func (e UnknownKey) Error() string

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL