hana

Version, currently 0.1.12 versions

github.com/cyangle/hana.cr

An implementation of JSON Patch and JSON Pointer for Crystal

0 stars
0 dependents
License: MIT

Installation

# Add this to your shard.yml
dependencies:
  hana:
    github: cyangle/hana.cr
    version: ~> 0.1.1

Then run:

shards install

shard.yml

Crystal
>= 1.13.2
License
MIT
Author
Chao Yang

Dependencies

Development Dependencies

  • ameba*github: crystal-ameba/amebadev

README

hana

License: MIT Crystal

Crystal port of the Ruby gem [hana]3.

Implementation of [JSON Patch]1 (RFC 6902) and [JSON Pointer]2 (RFC 6901).

Installation

  1. Add the dependency to your shard.yml:

    dependencies:
      hana:
        github: cyangle/hana.cr
        version: ~> 0.1.1
  2. Run shards install

Requirements: Crystal >= 1.13.2

Usage

JSON Patch

Apply patches to JSON documents. Supports all RFC 6902 operations: add, remove, replace, move, copy, and test.

require "hana"

doc = JSON.parse(%({
  "name": "John",
  "age": 30,
  "tags": ["developer"]
}))

# Create patch from JSON string
patch = Hana::Patch.new(%([
  { "op": "replace", "path": "/name", "value": "Jane" },
  { "op": "add", "path": "/email", "value": "jane@example.com" },
  { "op": "remove", "path": "/age" },
  { "op": "add", "path": "/tags/-", "value": "designer" }
]))

result = patch.apply(doc)
puts result.to_json
# {"name":"Jane","tags":["developer","designer"],"email":"jane@example.com"}

Patch Operations

OperationDescriptionExample
addAdd a value{"op": "add", "path": "/foo", "value": "bar"}
removeRemove a value{"op": "remove", "path": "/foo"}
replaceReplace a value{"op": "replace", "path": "/foo", "value": "baz"}
moveMove a value{"op": "move", "from": "/foo", "path": "/bar"}
copyCopy a value{"op": "copy", "from": "/foo", "path": "/bar"}
testTest a value matches{"op": "test", "path": "/foo", "value": "bar"}

Creating Patches

# From JSON string
patch = Hana::Patch.new(%([{"op": "add", "path": "/foo", "value": "bar"}]))

# From IO
patch = Hana::Patch.new(File.open("patches.json"))

# From Array
ops = [{"op" => JSON::Any.new("add"), "path" => JSON::Any.new("/foo"), "value" => JSON::Any.new("bar")}]
patch = Hana::Patch.new(ops)

JSON Pointer

Evaluate JSON Pointers to extract values from JSON documents.

require "hana"

doc = JSON.parse(%({
  "users": [
    {"name": "Alice", "role": "admin"},
    {"name": "Bob", "role": "user"}
  ],
  "config": {
    "debug": true
  }
}))

# Get nested values
pointer = Hana::Pointer.new("/users/0/name")
puts pointer.eval(doc) # "Alice"

pointer = Hana::Pointer.new("/users/1/role")
puts pointer.eval(doc) # "user"

pointer = Hana::Pointer.new("/config/debug")
puts pointer.eval(doc) # true

Development

hana runs tests from json-patch/json-patch-tests. Fetch the git submodule by running:

git submodule init
git submodule update

Install dependencies with:

shards install

Then run the tests with:

crystal spec

Linting

Format code with Crystal's built-in formatter:

crystal tool format

Run static analysis with Ameba:

bin/ameba

Contributing

  1. Fork it (https://github.com/cyangle/hana.cr/fork)
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

Contributors

License

This project is licensed under the MIT License - see the LICENSE file for details.