jsonpatch

package
v0.12.0 Latest Latest
Warning

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

Go to latest
Published: Nov 3, 2026 License: MIT Imports: 3 Imported by: 0

README

jsonpatch

import "github.com/kitsunium/sdk/pkg/v1/data/codec/jsonpatch"

Package jsonpatch computes the structural difference between two JSON documents as RFC 6902 operations — add, remove and replace, each at an RFC 6901 JSON Pointer — with the value each operation writes and the value it replaces or removes (ADR 0143).

edits, err := jsonpatch.Diff(before, after)
for _, e := range edits {
	fmt.Println(e.Op, e.Path, string(e.Old), "->", string(e.Value))
}

It is what a record's history needs to say what changed between two of its versions — a document store's versions are JSON for that reason — and the operations, applied in order to the first document, give the second. json.Marshal of the result is a JSON Patch document: RFC 6902's op, path and value, with the value replaced or removed under "old", a member RFC 6902 does not define for these operations and which a patch applier ignores.

How documents are compared

Each document must be exactly one JSON value, read strictly — no duplicated member name, valid UTF-8, no trailing data — or Diff returns NotJSON, naming which document and the offset, never a byte of it. Values are compared as RFC 6902 §4.6 compares them: strings once unescaped, numbers exactly by value (1, 1.0 and 1e0 are one number, and no float is involved), arrays element by element, objects by member name whatever their order.

What the operations are

Two objects: a member only the first has is removed, one only the second has is added, and one both have is compared in turn, members in byte order of their names — the same two documents always give the same operations. Two arrays: the elements both keep in order are found, after the equal ones at both ends, and between two kept elements the removed and the added are paired in order and compared, the rest removed or added — so an insertion in the middle is one add. An index is that of the array as the operations before have left it, as RFC 6902 applies them. Past a bound on the elements to align, those in the middle are paired by position: a longer patch, still a correct one. Anything else that differs is replaced whole; two roots of different kinds are one replace at "".

It emits no move, copy or test, and applies no patch.

Index

Constants

const Add Op = "add"

Add adds a member, or inserts an element before the one at the index.

Initialised with github.com/kitsunium/sdk/internal/service/data/codec/jsonpatch.Add.

const CodeNotJSON errs.Code = 219649

CodeNotJSON is the code of NotJSON (0.3.90.1), for errs.HasCode.

Initialised with github.com/kitsunium/sdk/internal/core/data/codec/jsonpatch.CodeNotJSON.

Code 0.3.90.1

const Remove Op = "remove"

Remove removes a member, or the element at the index.

Initialised with github.com/kitsunium/sdk/internal/service/data/codec/jsonpatch.Remove.

const Replace Op = "replace"

Replace replaces the value at the path, the whole document at "".

Initialised with github.com/kitsunium/sdk/internal/service/data/codec/jsonpatch.Replace.

Variables

var NotJSON *errs.Error

NotJSON refuses a document that is not exactly one JSON value; its fields name the document — "from" or "to" — and the offset, never its content.

Initialised with github.com/kitsunium/sdk/internal/core/data/codec/jsonpatch.NotJSON.

Code 0.3.90.1 · reason NOT_JSON · public "A document to compare is not a JSON value"

func Diff

func Diff(from []byte, to []byte) ([]Edit, error)

Diff returns the operations that turn the JSON document from into the JSON document to, in the order they apply — an empty slice when the two are the same value — or NotJSON.

type Edit

Edit is one operation of a diff: its Op, its Path, the Value it writes (add, replace) and the Old value it replaces or removes (replace, remove).

type Edit = svcjsonpatch.EditValue

Edit is an alias of github.com/kitsunium/sdk/internal/service/data/codec/jsonpatch.EditValue, declared as:

type Edit struct {
	// Op is add, remove or replace.
	Op    Op              `json:"op"`
	// Path is the RFC 6901 JSON Pointer of the value the operation changes.
	Path  string          `json:"path"`
	// Value is the value the operation writes: add and replace; absent for
	// remove.
	Value json.RawMessage `json:"value,omitempty"`
	// Old is the value the operation replaces or removes: replace and
	// remove; absent for add.
	Old   json.RawMessage `json:"old,omitempty"`
}

type Op

Op is what an operation does, as RFC 6902 names it.

type Op = svcjsonpatch.Op

Op is an alias of github.com/kitsunium/sdk/internal/service/data/codec/jsonpatch.Op, declared as:

type Op string

Generated from docs/api by tools/genindex.

Documentation

Overview

Package jsonpatch computes the structural difference between two JSON documents as RFC 6902 operations — add, remove and replace, each at an RFC 6901 JSON Pointer — with the value each operation writes and the value it replaces or removes (ADR 0143).

edits, err := jsonpatch.Diff(before, after)
for _, e := range edits {
	fmt.Println(e.Op, e.Path, string(e.Old), "->", string(e.Value))
}

It is what a record's history needs to say what changed between two of its versions — a document store's versions are JSON for that reason — and the operations, applied in order to the first document, give the second. json.Marshal of the result is a JSON Patch document: RFC 6902's op, path and value, with the value replaced or removed under "old", a member RFC 6902 does not define for these operations and which a patch applier ignores.

How documents are compared

Each document must be exactly one JSON value, read strictly — no duplicated member name, valid UTF-8, no trailing data — or Diff returns NotJSON, naming which document and the offset, never a byte of it. Values are compared as RFC 6902 §4.6 compares them: strings once unescaped, numbers exactly by value (1, 1.0 and 1e0 are one number, and no float is involved), arrays element by element, objects by member name whatever their order.

What the operations are

Two objects: a member only the first has is removed, one only the second has is added, and one both have is compared in turn, members in byte order of their names — the same two documents always give the same operations. Two arrays: the elements both keep in order are found, after the equal ones at both ends, and between two kept elements the removed and the added are paired in order and compared, the rest removed or added — so an insertion in the middle is one add. An index is that of the array as the operations before have left it, as RFC 6902 applies them. Past a bound on the elements to align, those in the middle are paired by position: a longer patch, still a correct one. Anything else that differs is replaced whole; two roots of different kinds are one replace at "".

It emits no move, copy or test, and applies no patch.

Index

Constants

CodeNotJSON is the code of NotJSON (0.3.90.1), for errs.HasCode.

Variables

NotJSON refuses a document that is not exactly one JSON value; its fields name the document — "from" or "to" — and the offset, never its content.

Functions

This section is empty.

Types

type Edit

type Edit = svcjsonpatch.EditValue

Edit is one operation of a diff: its Op, its Path, the Value it writes (add, replace) and the Old value it replaces or removes (replace, remove).

func Diff

func Diff(from, to []byte) ([]Edit, error)

Diff returns the operations that turn the JSON document from into the JSON document to, in the order they apply — an empty slice when the two are the same value — or NotJSON.

type Op

type Op = svcjsonpatch.Op

Op is what an operation does, as RFC 6902 names it.

const (
	// Add adds a member, or inserts an element before the one at the index.
	Add Op = svcjsonpatch.Add
	// Remove removes a member, or the element at the index.
	Remove Op = svcjsonpatch.Remove
	// Replace replaces the value at the path, the whole document at "".
	Replace Op = svcjsonpatch.Replace
)

The three operations a diff emits.

Jump to

Keyboard shortcuts

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