Letterpress.CanonicalJSON (Letterpress v0.1.0)

Copy Markdown View Source

Encodes JSON-compatible data into Letterpress's deterministic byte form.

Object keys are converted to strings and sorted lexically at every depth. Arrays keep their order, and no insignificant whitespace is emitted. Letterpress normalizes public input before it reaches this module, so callers should pass only maps, lists, strings, finite numbers, booleans, and nil.

Example

iex> Letterpress.CanonicalJSON.encode!(%{"z" => 1, "a" => [true, nil]})
~s({"a":[true,null],"z":1})

Summary

Functions

Encodes a JSON-compatible value.

Encodes a JSON-compatible value or raises for unsupported input.

Returns the lowercase SHA-256 digest of the canonical bytes.

Functions

encode(value)

@spec encode(term()) :: {:ok, binary()} | {:error, term()}

Encodes a JSON-compatible value.

Returns {:error, exception} instead of raising when the value cannot be represented by this canonical form.

Example

iex> Letterpress.CanonicalJSON.encode(%{b: 2, a: 1})
{:ok, ~s({"a":1,"b":2})}

encode!(value)

@spec encode!(term()) :: binary()

Encodes a JSON-compatible value or raises for unsupported input.

Use encode/1 at caller-controlled boundaries where invalid data is an expected failure.

hash(value)

@spec hash(term()) :: String.t()

Returns the lowercase SHA-256 digest of the canonical bytes.

Maps with the same normalized content hash identically regardless of their insertion order.

Example

iex> left = %{"b" => 2, "a" => 1}
iex> right = %{"a" => 1, "b" => 2}
iex> Letterpress.CanonicalJSON.hash(left) == Letterpress.CanonicalJSON.hash(right)
true