StatifierUI.Value (StatifierUI v0.1.0)

Copy Markdown View Source

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

decode(map)

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

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}

encode(date)

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

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}