# `Ascii.Options`
[🔗](https://github.com/houllette/ascii_art/blob/main/lib/ascii/options.ex#L1)

Checks options from outside (code, LiveView params and session, the CLI)
against a piece's defaults.

Every key must name one of the piece's options. String keys are compared
with the names of the defaults, so input never creates an atom. Every value
must have the shape of its default:

| default | accepted |
| --- | --- |
| number | a number, or a string that reads as one |
| boolean | a boolean, or `"true"` / `"false"` |
| string | a valid UTF-8 string, cut to 256 characters |
| `nil` | `nil`, or a number as above |
| list | a list whose entries match the default's entries (any string, if the default is empty); or JSON text for one; or, for a list of strings, comma-separated text, each entry trimmed |
| map | a map whose keys name some default entry's keys, values checked the same way |

Numbers are clamped to the piece's `meta.bounds` for that option, or to
±1,000,000. A bound reaches inside an option that holds lists or maps: a
range `{lo, hi}` holds every number within it, and a map of ranges by key
holds each map's values, `%{processes: %{pid: {0, 4_294_967_295}}}`; a
number with no range of its own keeps the million. Lists are cut to 256
entries.

Where a default cannot show what an option takes (an empty list that takes
numbers), the piece's `meta.shapes` gives an example to check against
instead: `%{values: [0.0]}` takes a list of numbers.

# `error`

```elixir
@type error() :: {:error, {:invalid_option, term()}}
```

# `cast`

```elixir
@spec cast(meta :: Ascii.Meta.t(), given :: map() | keyword(), base :: map() | nil) ::
  {:ok, map()} | error()
```

The piece's options: `base` (its defaults, unless given), with `given`
cast and merged over them.

# `known_key`

```elixir
@spec known_key(defaults :: map(), key :: term()) :: {:ok, atom()} | :error
```

The atom naming one of `defaults`' keys, given that atom or its name as a
string. Never creates an atom.

---

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