# `Rupa.Codec`
[🔗](https://github.com/zero-one-group/rupa/blob/v0.1.0/lib/rupa/codec.ex#L1)

What `Rupa.compile/1` hands back: a staged schema and the decoder built from it.

You do not call the decoder yourself — `Rupa.decode/3` does, because the same call has to
work for a codec compiled into a module in M3. What a codec is good for on its own is
`Rupa.explain/1`, which prints the staged program it carries.

# `t`

```elixir
@type t() :: %Rupa.Codec{
  decode: Rupa.Closure.decoder(),
  defs: %{required(atom()) =&gt; Rupa.Closure.decoder()},
  encode: Rupa.Closure.decoder(),
  encode_defs: %{required(atom()) =&gt; Rupa.Closure.decoder()},
  json: Rupa.Closure.decoder(),
  json_defs: %{required(atom()) =&gt; Rupa.Closure.decoder()},
  program: Rupa.IR.program(),
  schema: term()
}
```

# `new`

```elixir
@spec new(term(), Rupa.IR.program()) :: t()
```

Builds every direction for a staged program and wraps them together.

Three trees rather than two since M7: decode, encode to a wire term, and encode straight to
JSON iodata. `Rupa.decode_json/3` needs no tree of its own — it parses and then decodes.

`Rupa.compile/1` is the way in; this takes the normalised schema and the staged program:

    schema = Rupa.Schema.normalize(%{name: Rupa.T.string()})
    {:ok, program} = Rupa.Stage.run(schema)
    Rupa.Codec.new(schema, program)
    #=> #Rupa.Codec<object (1 field, unknown: strip)>

---

*Consult [api-reference.md](api-reference.md) for complete listing*
