Skip to content

alii/squirtle

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

27 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

squirtle

Package Version Hex Docs

A JSON Patch (RFC 6902) implementation for Gleam.

Installation

gleam add squirtle@2

Usage

Applying Patches

import gleam/io
import squirtle.{String, Add, Replace, Remove}

pub fn main() {
  let assert Ok(doc) = squirtle.parse("{\"name\": \"John\", \"age\": 30}")

  let patches = [
    Replace(path: "/name", value: String("Jane")),
    Add(path: "/email", value: String("[email protected]")),
    Remove(path: "/age"),
  ]

  case squirtle.apply(doc, patches) {
    Ok(result) -> io.println(squirtle.to_string(result))
    // => {"name":"Jane","email":"[email protected]"}
    Error(err) -> io.println("Patch failed: " <> squirtle.error_to_string(err))
  }
}

Generating Diffs

import gleam/dict
import squirtle.{String, Int, Object}

pub fn main() {
  let old = Object(dict.from_list([#("name", String("John"))]))
  let new = Object(dict.from_list([
    #("name", String("Jane")),
    #("age", Int(30)),
  ]))

  let patches = squirtle.diff(from: old, to: new)
  // => [Replace("/name", String("Jane")), Add("/age", Int(30))]

  let assert Ok(result) = squirtle.apply(old, patches)
  // result == new
}

Decoding from JSON

import gleam/dynamic/decode
import gleam/json
import squirtle

pub fn apply_patch_request(doc_json: String, patches_json: String) {
  let assert Ok(doc) = json.parse(doc_json, squirtle.decoder())
  let assert Ok(patches) = json.parse(patches_json, decode.list(squirtle.patch_decoder()))

  squirtle.apply(doc, patches)
}

Supported Operations

All operations follow RFC 6902:

Operation Description Example
add Add a value at a path {"op": "add", "path": "/email", "value": "[email protected]"}
remove Remove a value at a path {"op": "remove", "path": "/age"}
replace Replace a value at a path {"op": "replace", "path": "/name", "value": "Jane"}
copy Copy a value from one path to another {"op": "copy", "from": "/name", "path": "/username"}
move Move a value from one path to another {"op": "move", "from": "/old", "path": "/new"}
test Test that a value equals expected {"op": "test", "path": "/name", "value": "John"}

JSON Pointer Paths

Paths use JSON Pointer (RFC 6901) syntax:

Path Meaning
"" Root document
/foo Property "foo" in the root object
/foo/bar Property "bar" nested in "foo"
/foo/0 First element of array at "foo"
/foo/- Append to array at "foo" (add only)
/foo~0bar Property "bar" ( escaped as ~0)
/foo~1bar Property "/bar" (/ escaped as ~1)

API Reference

Further documentation can be found at https://hexdocs.pm/squirtle.

Development

gleam test  # Run the tests

About

Implementation of RFC 6902 in Gleam (JSON Patch)

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages