JsonMergePatch (JsonMergePatch v0.1.0)

Copy Markdown View Source

RFC 7396 JSON Merge Patch.

Applies a patch to a decoded JSON value. Maps use string keys, matching JSON.decode/1. Structs and atom-key maps are rejected.

Examples

iex> JsonMergePatch.apply_patch(
...>   %{"a" => "b", "c" => %{"d" => "e", "f" => "g"}},
...>   %{"a" => "z", "c" => %{"f" => nil}}
...> )
{:ok, %{"a" => "z", "c" => %{"d" => "e"}}}

Behaviour

  • A non-object patch replaces the target.
  • An object patch merges into an object target. A non-object target becomes %{} first.
  • A patch value of nil deletes that key on the target.
  • An array patch replaces the whole value.

See RFC 7396.

Summary

Types

A decoded JSON value.

Option for apply_patch/3.

Keyword options for apply_patch/3.

Functions

Applies a JSON Merge Patch to target.

Same as apply_patch/3 but raises JsonMergePatch.Error instead of returning {:error, exception}.

Types

json()

@type json() ::
  nil
  | boolean()
  | number()
  | String.t()
  | [json()]
  | %{optional(String.t()) => json()}

A decoded JSON value.

opt()

@type opt() :: {:max_depth, pos_integer() | :infinity}

Option for apply_patch/3.

opts()

@type opts() :: [opt()]

Keyword options for apply_patch/3.

Functions

apply_patch(target, patch, opts \\ [])

@spec apply_patch(term(), term(), opts()) ::
  {:ok, json()} | {:error, JsonMergePatch.Error.t()}

Applies a JSON Merge Patch to target.

target and patch are decoded JSON values. Maps use string keys. Structs and atom-key maps are rejected.

Returns {:ok, json} or {:error, JsonMergePatch.Error.t()}.

Options

  • :max_depth - maximum nesting in the patch (objects and arrays). The top-level patch value is depth 1. Defaults to :infinity. Callers applying patches from untrusted sources should set :max_depth.

Examples

iex> JsonMergePatch.apply_patch(%{"a" => "b"}, %{"a" => "c"})
{:ok, %{"a" => "c"}}

iex> JsonMergePatch.apply_patch(%{a: 1}, %{})
{:error, %JsonMergePatch.Error{reason: :invalid_target}}

iex> JsonMergePatch.apply_patch(%{"a" => 1}, %{"a" => %{"b" => 2}}, max_depth: 1)
{:error, %JsonMergePatch.Error{reason: :max_depth_exceeded}}

apply_patch!(target, patch, opts \\ [])

@spec apply_patch!(term(), term(), opts()) :: json()

Same as apply_patch/3 but raises JsonMergePatch.Error instead of returning {:error, exception}.

Examples

iex> JsonMergePatch.apply_patch!(%{"a" => "b"}, %{"a" => "c"})
%{"a" => "c"}