Rupa.Closure (rupa v0.1.0)

Copy Markdown View Source

The closure backend: Rupa.IR in, a tree of anonymous functions out.

One function per IR node, each closing over everything the node decided at staging time — the compiled regex, the format's decoder, the wire key, the default. A decode is then a walk down a tree of calls with no interpretation and no lookups, except at a recursive ref, which is the one place a table is consulted.

Every decoder has the same shape, (value, ctx) -> {:ok, decoded} | {:error, [Rupa.Error]), where ctx is {mode, defs}. Paths are built on the way back up: a leaf reports an error with an empty path and each parent prepends its own segment, so a successful decode allocates nothing for paths at all.

Summary

Functions

Builds the root decoder and the table the recursive refs resolve against.

The same as build/1, and used the same way, in the other direction.

The other direction again, straight to JSON iodata rather than to a wire term.

Types

ctx()

@type ctx() :: {:halt | :collect, %{required(atom()) => decoder()}}

decoder()

@type decoder() :: (term(), ctx() -> {:ok, term()} | {:error, [Rupa.Error.t()]})

Functions

build(map)

@spec build(Rupa.IR.program()) :: {decoder(), %{required(atom()) => decoder()}}

Builds the root decoder and the table the recursive refs resolve against.

Rupa.Codec.new/2 calls this and its two siblings; you reach what they build through Rupa.decode/3 rather than by holding one:

{:ok, program} = Rupa.Stage.run(%{name: Rupa.T.string()})
{decode, defs} = Rupa.Closure.build(program)
decode.(%{"name" => "Ada"}, {:halt, defs})
#=> {:ok, %{name: "Ada"}}

build_encoder(program)

@spec build_encoder(Rupa.IR.program()) ::
  {decoder(), %{required(atom()) => decoder()}}

The same as build/1, and used the same way, in the other direction.

build_json(program)

@spec build_json(Rupa.IR.program()) :: {decoder(), %{required(atom()) => decoder()}}

The other direction again, straight to JSON iodata rather than to a wire term.

Built and used exactly as build/1 is; what it hands back emits bytes rather than a term.