A document's map form and JSON form, exact inverses for valid values (spec/01 §6).
The value is the document as Elixir holds it: atom keys where the type has a key,
string names elsewhere, atoms, times. Its map form is JSON-ready: string keys, and a
tag (Macaw.Layers.Tags) for every value JSON can't express. Its JSON form is that
map encoded. For a valid value:
from_map(to_map(value)) == {:ok, value}
to_map(from_map(map)) == {:ok, map} # for a map to_map/2 wroteA document type implements this behavior: its tag table, the keys it reads as atoms, and
the atoms a $atom may spell, each a closed table (Macaw.Layers.Vocabulary), so no
atom is ever made from a document. A type with values of its own (a struct, a tuple)
writes and reads them through encode_value/1 and decode_value/2, under its own
live tags.
The kernel's terms:
| Value | Map form |
|---|---|
nil, a boolean, a number, a string | as it is |
| another atom | {"$atom": "spelling"}, read back through atoms/0 |
a DateTime in Etc/UTC | {"$time": "ISO 8601"} |
| a list | a list |
| a map | an object: an atom key by its spelling, a string key as it is, escaped when it starts with $ |
A function, a PID, a reference, a port, a tuple or a struct the type does not write has
no form: it is refused at its path as {:type, :term}.
Summary
Callbacks
The atoms a $atom may spell in this type's documents.
The value of one of the type's own live tags, its payload already read, or :default
when the tag or payload is not one it reads.
A value of the type's own, in its map form, or :default for the kernel's rules.
The keys the type reads as atoms, by spelling.
The type's tag table: a module that uses Macaw.Layers.Tags.
Functions
One term's map form, for a type writing its own tag's payload (spec/01 §6): {:ok, form},
or every value and key without one, by path from the term.
The value a JSON document holds, read through every gate (Macaw.Layers.Document.read/3)
and then from its map form. type implements this behavior, Macaw.Layers.Version and
Macaw.Layers.Document.
The value a map form holds: its tags held to the type's table, its keys read against the
type's keys, its $atoms against the type's atoms; {:ok, value} or every fault.
The value's JSON form.
The value's map form: {:ok, map}, or every value and key without one, by path.
Callbacks
@callback atoms() :: Macaw.Layers.Vocabulary.table()
The atoms a $atom may spell in this type's documents.
The value of one of the type's own live tags, its payload already read, or :default
when the tag or payload is not one it reads.
A value of the type's own, in its map form, or :default for the kernel's rules.
@callback keys() :: Macaw.Layers.Vocabulary.table()
The keys the type reads as atoms, by spelling.
@callback tags() :: module()
The type's tag table: a module that uses Macaw.Layers.Tags.
Functions
@spec encode_term(term(), module()) :: {:ok, term()} | {:error, [Macaw.Layers.Fault.t(), ...]}
One term's map form, for a type writing its own tag's payload (spec/01 §6): {:ok, form},
or every value and key without one, by path from the term.
@spec from_json(binary(), module(), [Macaw.Layers.Document.option()]) :: {:ok, map()} | {:error, [Macaw.Layers.Fault.t(), ...]}
The value a JSON document holds, read through every gate (Macaw.Layers.Document.read/3)
and then from its map form. type implements this behavior, Macaw.Layers.Version and
Macaw.Layers.Document.
@spec from_map(map(), module()) :: {:ok, map()} | {:error, [Macaw.Layers.Fault.t(), ...]}
The value a map form holds: its tags held to the type's table, its keys read against the
type's keys, its $atoms against the type's atoms; {:ok, value} or every fault.
@spec to_json(map(), module()) :: {:ok, binary()} | {:error, [Macaw.Layers.Fault.t(), ...]}
The value's JSON form.
@spec to_map(map(), module()) :: {:ok, map()} | {:error, [Macaw.Layers.Fault.t(), ...]}
The value's map form: {:ok, map}, or every value and key without one, by path.