Codec for ADR-0005's JSON encoding of the value domain predicator's
Predicator.Types module defines (its value/0 type).
decode/1 reads a JSON-decoded term (as produced by the stdlib JSON
module) and recovers the predicator value it encodes, resolving the
$-prefixed one-key tagged shapes ADR-0005 reserves: $undefined,
$date, $datetime, $duration. encode/1 is the inverse, present so
the codec is round-trip testable; it is not wired to any writer.
JSON-native values (booleans, numbers, strings, nil, lists, ordinary
maps) map to themselves in both directions. JSON null always decodes to
nil - a present, null value - never to the :undefined sentinel, which
has its own tagged encoding because absence has no positional spelling
inside a list or map value.
Durations are the one value that does not round-trip identically:
StatifierUI.Shape.duration?/1 recognizes any non-empty subset of the
eight units (predicator's parser emits seven, omitting :milliseconds),
while encode/1 always writes all eight, filling absent units with 0.
The re-decoded value is therefore canonical rather than identical to the
input, and semantically equal to it.
encode/1 is closed over predicator's value domain (ADR-0005): the
JSON-native scalars, Date, DateTime, durations, string- or
atom-keyed maps, and lists of the above. A term outside that domain -
a bare atom other than nil, :undefined, true, or false, a pid,
tuple, reference, port, function, or a struct other than Date or
DateTime - is rejected with {:error, {:unsupported_value, term}}
rather than passed through or allowed to raise.
Summary
Functions
Decodes a JSON-decoded term into a predicator value.
Encodes a predicator value into its ADR-0005 JSON-native term.
Functions
Decodes a JSON-decoded term into a predicator value.
Recurses through lists and map values. A one-key map whose key starts
with $ and is not one of the four reserved tags is an error: ADR-0005
reserves the whole one-key $-prefixed shape, so an unrecognized tag is a
spec violation on the producer's side rather than a host map to pass
through. A multi-key map containing a $-prefixed key is an ordinary host
map.
Examples
iex> StatifierUI.Value.decode(1999)
{:ok, 1999}
iex> StatifierUI.Value.decode(nil)
{:ok, nil}
iex> StatifierUI.Value.decode(%{"$undefined" => true})
{:ok, :undefined}
Encodes a predicator value into its ADR-0005 JSON-native term.
The inverse of decode/1. Not wired to any writer; present so the codec
is round-trip testable.
A term outside predicator's closed value domain - a bare atom other than
nil, :undefined, true, or false, a pid, tuple, reference, port,
function, or a struct other than Date or DateTime - returns
{:error, {:unsupported_value, term}}. This function never raises.
Examples
iex> StatifierUI.Value.encode(:undefined)
{:ok, %{"$undefined" => true}}
iex> StatifierUI.Value.encode(1999)
{:ok, 1999}