gleamson/patch

JSON Patch (RFC 6902): describe and apply changes to a gleamson.Json document, and compute the difference between two documents.

A patch is a list of Operations applied in order and atomically — if any operation fails, apply returns an error and the original document is left untouched. Paths are JSON Pointers (RFC 6901).

import gleamson
import gleamson/patch.{Add, Replace}

let assert Ok(doc) = gleamson.parse("{\"a\":1,\"b\":[10]}")
let assert Ok(out) =
  patch.apply(doc, [Replace("/a", gleamson.Int(2)), Add("/b/-", gleamson.Int(20))])
// out == {"a":2,"b":[10,20]}

Types

A single JSON Patch operation. Paths and from are JSON Pointer strings.

pub type Operation {
  Add(path: String, value: gleamson.Json)
  Remove(path: String)
  Replace(path: String, value: gleamson.Json)
  Move(from: String, path: String)
  Copy(from: String, path: String)
  Test(path: String, value: gleamson.Json)
}

Constructors

  • Add(path: String, value: gleamson.Json)
  • Remove(path: String)
  • Replace(path: String, value: gleamson.Json)
  • Move(from: String, path: String)
  • Copy(from: String, path: String)
  • Test(path: String, value: gleamson.Json)

Why applying a patch failed.

pub type PatchError {
  PathNotFound(path: String)
  InvalidPath(path: String)
  TestFailed(
    path: String,
    expected: gleamson.Json,
    actual: gleamson.Json,
  )
}

Constructors

  • PathNotFound(path: String)

    A path referred to a location that does not exist.

  • InvalidPath(path: String)

    A path was not a valid JSON Pointer for the target.

  • TestFailed(
      path: String,
      expected: gleamson.Json,
      actual: gleamson.Json,
    )

    A Test operation did not match.

Values

pub fn apply(
  json: gleamson.Json,
  operations: List(Operation),
) -> Result(gleamson.Json, PatchError)

Apply a patch to a document. All operations succeed, or none are applied.

pub fn decoder() -> fn(gleamson.Json) -> #(
  List(Operation),
  List(decode.DecodeError),
)

A decoder for a JSON Patch document (an array of operations). Pair it with gleamson.parse / decode.from_string to read a patch off the wire.

pub fn diff(
  from from: gleamson.Json,
  to to: gleamson.Json,
) -> List(Operation)

Compute a patch that turns from into to. The result is correct but not guaranteed minimal: array changes are emitted positionally rather than by detecting moves.

pub fn to_json(operations: List(Operation)) -> gleamson.Json

Encode a patch as a JSON value (an array of operation objects).

Search Document