# `Selecto.Domain.Choices`

Choice-source membership helpers.

This module is intentionally metadata-only in its first slice. It can resolve
a working-domain field to its declared choice source and build a stable
membership request, but it only proves membership when a caller supplies an
explicit resolver.

# `choice_error`

```elixir
@type choice_error() :: %{code: atom(), message: String.t(), path: [term()]}
```

# `field`

```elixir
@type field() :: atom() | String.t()
```

# `binding`

```elixir
@spec binding(map(), field()) :: {:ok, map()} | {:error, choice_error()}
```

Resolves the choice-source binding for a working-domain field.

Rich references use `reference.choice_source`; compact bindings use
`choice_source` directly on the column metadata.

# `choice_source_options_request`

```elixir
@spec choice_source_options_request(map(), atom() | String.t(), map() | keyword()) ::
  {:ok, Selecto.Domain.Choices.OptionsRequest.t()} | {:error, choice_error()}
```

Builds an option-list request directly from a declared choice source.

# `invalid`

```elixir
@spec invalid(atom() | String.t(), map() | keyword()) ::
  Selecto.Domain.Choices.Result.t()
```

Builds an invalid membership result.

# `list_options`

```elixir
@spec list_options(map(), field(), map() | keyword()) ::
  {:ok, Selecto.Domain.Choices.OptionsResult.t()}
  | {:error, Selecto.Domain.Choices.OptionsResult.t() | choice_error()}
```

Resolves an option-list request through an explicit resolver.

Without a resolver this returns an `:unknown` result. A resolver may be a
one-arity function that receives an `%OptionsRequest{}` and returns an
`%OptionsResult{}`, `{:ok, %OptionsResult{}}`, or
`{:error, %OptionsResult{}}`.

# `options_error`

```elixir
@spec options_error(atom() | String.t(), map() | keyword()) ::
  Selecto.Domain.Choices.OptionsResult.t()
```

Builds an error option-list result.

# `options_request`

```elixir
@spec options_request(map(), field(), map() | keyword()) ::
  {:ok, Selecto.Domain.Choices.OptionsRequest.t()} | {:error, choice_error()}
```

Builds a choice-source option-list request.

By default the target is treated as a working-domain field and resolved
through its field binding. Pass `by: :choice_source` to build the request
directly from a declared choice source.

# `options_resolved`

```elixir
@spec options_resolved([map()], map() | keyword()) ::
  Selecto.Domain.Choices.OptionsResult.t()
```

Builds a resolved option-list result.

# `options_unknown`

```elixir
@spec options_unknown(atom() | String.t(), map() | keyword()) ::
  Selecto.Domain.Choices.OptionsResult.t()
```

Builds an unknown option-list result.

# `request`

```elixir
@spec request(map(), field(), term(), map() | keyword()) ::
  {:ok, Selecto.Domain.Choices.Request.t()} | {:error, choice_error()}
```

Builds a choice-source membership request for a field/value pair.

The domain may be either an authored domain map or a normalized domain from
`Selecto.Domain.normalize/1`. Invalid domain contracts and unbound fields
return structured errors.

# `unknown`

```elixir
@spec unknown(atom() | String.t(), map() | keyword()) ::
  Selecto.Domain.Choices.Result.t()
```

Builds an unknown membership result.

# `valid`

```elixir
@spec valid(atom() | String.t(), map() | keyword()) ::
  Selecto.Domain.Choices.Result.t()
```

Builds a valid membership result.

# `valid_choice?`

```elixir
@spec valid_choice?(map(), field(), term(), map() | keyword()) :: boolean()
```

Boolean convenience for callers that already supplied a resolver.

Unknown and invalid results both return `false`; use `validate_choice/4` when
callers need to distinguish those states.

# `validate_choice`

```elixir
@spec validate_choice(map(), field(), term(), map() | keyword()) ::
  {:ok, Selecto.Domain.Choices.Result.t()}
  | {:error, Selecto.Domain.Choices.Result.t() | choice_error()}
```

Validates a choice-source membership question.

Without a resolver this returns an `:unknown` result instead of guessing. A
resolver may be a one-arity function that receives a `%Request{}` and returns
a `%Result{}`, `{:ok, %Result{}}`, or `{:error, %Result{}}`.

---

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