# `Macaw.Component.Slot`
[🔗](https://github.com/dcoai/macaw_component/blob/v0.1.2/lib/macaw/component/slot.ex#L1)

A slot: a typed input, `%{requires: %{role => requirement}, doc: "…"}` (spec/01 §1.3).

Each role is a field the component reads from the slot's source, with what it requires
of that field. `check/3` checks a binding of the slot to a source's schema before any
data flows, so a component author and every host check bindings the same way.

# `requirement`

```elixir
@type requirement() :: %{
  type: [atom(), ...],
  window: boolean(),
  identity: boolean(),
  quantity: atom() | nil,
  many: boolean(),
  optional: boolean(),
  doc: String.t() | nil
}
```

# `t`

```elixir
@type t() :: %{
  requires: %{required(String.t()) =&gt; requirement()},
  doc: String.t() | nil
}
```

# `check`

```elixir
@spec check(t(), Macaw.Data.Schema.t(), map()) ::
  :ok | {:error, [Macaw.Component.fault(), ...]}
```

Checks a binding of a slot (as `new/1` builds it) to a source of `schema`, `fields`
mapping each role to its field, or for a `many` role a non-empty list of fields. `:ok`
or every fault at once, each at `[role]`. A `window` role left unbound reads the
schema's window field.

    iex> {:ok, slot} = Macaw.Component.Slot.new(%{requires: %{"x" => %{type: :time, window: true}, "y" => %{type: :number}}})
    iex> schema = Macaw.Data.Schema.new!(%{t: %{type: :time}, v: %{type: :number}})
    iex> Macaw.Component.Slot.check(slot, schema, %{"y" => "v"})
    :ok
    iex> Macaw.Component.Slot.check(slot, schema, %{})
    {:error, [{["y"], :unbound}]}

# `new`

```elixir
@spec new(term()) :: {:ok, t()} | {:error, [Macaw.Component.fault(), ...]}
```

A slot built from its declaration, every requirement's defaults filled in and `type`
always a list: `{:ok, slot}`, or `{:error, faults}` from the slot.

# `requirement_keys`

```elixir
@spec requirement_keys() :: [atom(), ...]
```

A requirement's keys, in order.

---

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