# `RequestSeal.StructuredFields.Schema`
[🔗](https://github.com/baselabs/request_seal/blob/v0.5.2/lib/request_seal/structured_fields/schema.ex#L1)

Explicit field type restrictions and RFC revision (RFC 9651 Section 2).

A schema names the RFC revision, the top-level type, the bare types allowed for
items (including inner-list items), the bare types allowed for parameters, and
whether inner lists are allowed. Bare types are `:integer`, `:decimal`,
`:string`, `:token`, `:bytes`, and `:boolean`; RFC 9651 additionally allows
`:date` and `:display_string`.

This is a type schema, not a complete field protocol or profile. The caller
selects it from the field's normative specification and checks any additional
semantic rules. No field name or recognized syntax selects a newer revision.
Directly constructed schemas undergo the same validation at each entry point.

# `bare_type`

```elixir
@type bare_type() ::
  :integer
  | :decimal
  | :string
  | :token
  | :bytes
  | :boolean
  | :date
  | :display_string
```

# `t`

```elixir
@type t() :: %RequestSeal.StructuredFields.Schema{
  inner_lists: boolean(),
  item_types: [bare_type()],
  parameter_types: [bare_type()],
  revision: :rfc8941 | :rfc9651,
  type: :item | :list | :dictionary
}
```

# `new`

```elixir
@spec new(map()) :: {:ok, t()} | {:error, RequestSeal.StructuredFields.Error.t()}
```

Construct an explicit type schema; no revision or item-type defaults.

## Parameters

  * `attrs` - a map using only these keys; unknown keys reject:
    * `:revision` (required) - `:rfc8941` or `:rfc9651`.
    * `:type` (required) - `:item`, `:list`, or `:dictionary`.
    * `:item_types` (required) - nonempty list of at most eight unique bare types
      defined by the revision.
    * `:parameter_types` - list of at most eight unique bare types defined by the
      revision; an empty list rejects every parameter. Defaults to all types in
      the selected revision.
    * `:inner_lists` - boolean, default `false`.

## Returns

  * `{:ok, %RequestSeal.StructuredFields.Schema{}}`.
  * `{:error, %RequestSeal.StructuredFields.Error{reason: :invalid_schema}}` -
    the only reason. Meanings: `RequestSeal.StructuredFields.Error`.

## Examples

    iex> {:ok, schema} = RequestSeal.StructuredFields.Schema.new(%{revision: :rfc9651, type: :list, item_types: [:token, :date]})
    iex> {schema.inner_lists, length(schema.parameter_types)}
    {false, 8}
    iex> RequestSeal.StructuredFields.Schema.new(%{revision: :rfc8941, type: :list, item_types: [:date]})
    {:error, %RequestSeal.StructuredFields.Error{reason: :invalid_schema}}
    iex> RequestSeal.StructuredFields.Schema.new(%{revision: :rfc8941, type: :list})
    {:error, %RequestSeal.StructuredFields.Error{reason: :invalid_schema}}

# `types`

Types defined by the selected revision; invalid revisions return an empty list.

## Parameters

  * `revision` - `:rfc8941` or `:rfc9651`; any other term returns `[]`.

## Returns

  * A list of bare type atoms in a fixed order.

## Examples

    iex> RequestSeal.StructuredFields.Schema.types(:rfc8941)
    [:integer, :decimal, :string, :token, :bytes, :boolean]
    iex> RequestSeal.StructuredFields.Schema.types(:rfc9651) -- RequestSeal.StructuredFields.Schema.types(:rfc8941)
    [:date, :display_string]
    iex> RequestSeal.StructuredFields.Schema.types(:draft)
    []

# `validate`

```elixir
@spec validate(term()) :: :ok | {:error, RequestSeal.StructuredFields.Error.t()}
```

Validate revision, top-level type, and all bare-type restrictions.

Applies the rules of `new/1` to an existing struct, including one built or
modified directly. Every parse and serialize entry point runs this check.

## Parameters

  * `schema` - any term; only a `RequestSeal.StructuredFields.Schema` struct can pass.

## Returns

  * `:ok`.
  * `{:error, %RequestSeal.StructuredFields.Error{reason: :invalid_schema}}` -
    the only reason. Meanings: `RequestSeal.StructuredFields.Error`.

## Examples

    iex> {:ok, schema} = RequestSeal.StructuredFields.Schema.new(%{revision: :rfc8941, type: :item, item_types: [:bytes]})
    iex> RequestSeal.StructuredFields.Schema.validate(schema)
    :ok
    iex> RequestSeal.StructuredFields.Schema.validate(%{schema | inner_lists: :yes})
    {:error, %RequestSeal.StructuredFields.Error{reason: :invalid_schema}}

---

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