binary

package
v0.7.10 Latest Latest
Warning

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

Go to latest
Published: Jul 30, 2026 License: MIT Imports: 10 Imported by: 0

README

Binary Codec for JSON Patch Operations

The binary codec serializes JSON Patch operations to MessagePack using the same operation tree as the compact codec.

The binary wire contract is protected by golden tests for MessagePack bytes, optional fields, parent-relative predicate paths, exact operation frame arity, and complete input consumption.

Format Overview

The binary codec uses MessagePack arrays with the same structure as the compact codec:

[opcode, path, ...args]

The payload is encoded as MessagePack bytes instead of JSON arrays. Present optional true flags are encoded as MessagePack integer 1; false flags are omitted. The decoder rejects booleans and other values in those marker slots.

Usage

import (
    "fmt"
    "log"

    "github.com/kaptinlin/jsonpatch"
    "github.com/kaptinlin/jsonpatch/codec/binary"
    "github.com/kaptinlin/jsonpatch/op"
)

func main() {
    ops := []jsonpatch.Op{
        op.NewAdd([]string{"user", "name"}, "Alice"),
        op.NewInc([]string{"user", "score"}, 100),
        op.NewStrIns([]string{"user", "bio"}, 0, "Hello! "),
        op.NewFlip([]string{"user", "active"}),
    }

    codec := binary.New()

    data, err := codec.Encode(ops)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("Binary size: %d bytes\n", len(data))

    decoded, err := codec.Decode(data)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(len(decoded))
}

Operation Support

The binary codec uses the same operation codes and path segment arrays as the compact codec:

Standard JSON Patch Operations (RFC 6902)
Operation Code Binary Format Struct Example
add 0 [0, path_array, value] {Op: "add", Path: "/foo", Value: 123}
remove 1 [1, path_array, oldValue?] {Op: "remove", Path: "/foo"}
replace 2 [2, path_array, value, oldValue?] {Op: "replace", Path: "/foo", Value: 456}
move 4 [4, path_array, from_array] {Op: "move", Path: "/bar", From: "/foo"}
copy 3 [3, path_array, from_array] {Op: "copy", Path: "/bar", From: "/foo"}
test 5 [5, path_array, value, not?] {Op: "test", Path: "/foo", Value: 123}
Extended Operations
Operation Code Binary Format Struct Example
flip 8 [8, path_array] {Op: "flip", Path: "/active"}
inc 9 [9, path_array, delta] {Op: "inc", Path: "/count", Inc: 5}
str_ins 6 [6, path_array, pos, str] {Op: "str_ins", Path: "/text", Pos: 0, Str: "Hi"}
str_del 7 [7, path_array, pos, str] or [7, path_array, pos, 0, len] {Op: "str_del", Path: "/text", Pos: 5, Len: 3}
split 10 [10, path_array, pos, props?] {Op: "split", Path: "/obj", Pos: 2, Props: {...}}
extend 12 [12, path_array, props, deleteNull?] {Op: "extend", Path: "/config", Props: {...}}
merge 11 [11, path_array, pos, props?] {Op: "merge", Path: "/obj/1", Pos: 0, Props: {...}}
JSON Predicate Operations
Operation Code Binary Format Struct Example
defined 31 [31, path_array] {Op: "defined", Path: "/field"}
undefined 38 [38, path_array] {Op: "undefined", Path: "/field"}
contains 30 [30, path_array, value, ignoreCase?] {Op: "contains", Path: "/text", Value: "hello"}
starts 37 [37, path_array, value, ignoreCase?] {Op: "starts", Path: "/text", Value: "Hello"}
ends 32 [32, path_array, value, ignoreCase?] {Op: "ends", Path: "/text", Value: ".com"}
matches 35 [35, path_array, pattern, ignoreCase?] {Op: "matches", Path: "/email", Value: ".*@.*"}
in 33 [33, path_array, values] {Op: "in", Path: "/role", Value: ["admin"]}
less 34 [34, path_array, value] {Op: "less", Path: "/age", Value: 30}
more 36 [36, path_array, value] {Op: "more", Path: "/score", Value: 100}
type 42 [42, path_array, type] {Op: "type", Path: "/data", Value: "string"}
test_type 39 [39, path_array, types] {Op: "test_type", Path: "/data", Type: ["string"]}
test_string 40 [40, path_array, pos, str, not?] {Op: "test_string", Path: "/text", Str: "test", Pos: 5}
test_string_len 41 [41, path_array, len, not?] {Op: "test_string_len", Path: "/text", Len: 10}
Second-Order Predicates

Child paths are encoded relative to the containing predicate path.

Operation Code Binary Format Struct Example
and 43 [43, path_array, ops[]] {Op: "and", Path: "/profile", Apply: [...]}
not 44 [44, path_array, ops[]] {Op: "not", Path: "/profile", Apply: [...]}
or 45 [45, path_array, ops[]] {Op: "or", Path: "/profile", Apply: [...]}

MessagePack Technical Details

Path Encoding

Paths are encoded as variable-length arrays:

[path_length, segment1, segment2, ...]

For example, path "/user/name" becomes:

[2, "user", "name"]  // Binary MessagePack representation
Value Encoding

Values use MessagePack's native type preservation:

  • Strings: Direct UTF-8 binary encoding
  • Numbers: Compact binary number representation
  • Objects: Recursive MessagePack object encoding
  • Arrays: Recursive MessagePack array encoding

API Reference

Codec Structure
type Codec struct{}

func New() *Codec
func (c *Codec) Encode(ops []jsonpatch.Op) ([]byte, error)
func (c *Codec) Decode(data []byte) ([]jsonpatch.Op, error)

Testing Contract

The codec has golden coverage for MessagePack bytes, optional-field omission, integer 1 true markers, and parent-relative composite predicate paths. Decode rejects invalid true markers with ErrInvalidTrueMarker, invalid operation frame lengths with ErrInvalidFrameArity, and trailing bytes or concatenated values with ErrTrailingData.

Documentation

Overview

Package binary implements a MessagePack-based binary codec for JSON Patch operations.

The binary codec uses the same operation tree as the compact codec: paths are encoded as segment arrays, optional true flags use integer 1 while false fields are omitted, and composite predicate children use paths relative to the containing predicate path.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrUnsupportedOp indicates an unknown or unsupported operation code.
	ErrUnsupportedOp = errors.New("unsupported operation code")
	// ErrInvalidPredicate indicates a composite predicate contains a non-predicate operation.
	ErrInvalidPredicate = errors.New("invalid predicate operation")
	// ErrNotSinglePredicate indicates a not operation has anything other than one child predicate.
	ErrNotSinglePredicate = errors.New("not operation requires exactly one predicate")
	// ErrInvalidTestTypeFormat indicates invalid types array for test_type predicate.
	ErrInvalidTestTypeFormat = errors.New("invalid test_type types format")
	// ErrInvalidValueType indicates the decoded value has an unexpected type.
	ErrInvalidValueType = errors.New("invalid value type")
	// ErrMapKeyNotString indicates a MessagePack object contains a non-string key.
	ErrMapKeyNotString = errors.New("map key must be a string")
	// ErrInvalidFrameArity indicates an operation frame has the wrong number of fields.
	ErrInvalidFrameArity = errors.New("invalid operation frame arity")
	// ErrInvalidTrueMarker indicates an optional true flag is not encoded as integer 1.
	ErrInvalidTrueMarker = errors.New("binary optional true marker must be integer 1")
	// ErrTrailingData indicates bytes remain after a complete patch value.
	ErrTrailingData = errors.New("trailing data after patch")
	// ErrNumberNotFinite indicates a coordinate is NaN or infinite.
	ErrNumberNotFinite = errors.New("numeric field must be finite")
	// ErrNumberNotInteger indicates a coordinate has a fractional component.
	ErrNumberNotInteger = errors.New("coordinate field must be an integer")
	// ErrNumberOutOfRange indicates a coordinate cannot be represented as int.
	ErrNumberOutOfRange = errors.New("coordinate field is outside the int range")
)

Functions

This section is empty.

Types

type Codec

type Codec struct{}

Codec encodes and decodes JSON Patch operations in MessagePack binary format.

func New added in v0.5.15

func New() *Codec

New creates a new binary Codec.

func (*Codec) Decode

func (c *Codec) Decode(data []byte) ([]internal.Op, error)

Decode deserializes operations from MessagePack binary format.

func (*Codec) Encode

func (c *Codec) Encode(ops []internal.Op) ([]byte, error)

Encode serializes operations into MessagePack binary format.

Jump to

Keyboard shortcuts

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