Pick one option from a set you define.
TypeSafeAPI.choice("Which team should handle this?",
billing: "Payments, invoicing, refunds",
technical: "Bugs, outages, integrations",
sales: nil
)Criteria are an ordered list of {key, description} pairs — a keyword list
or a list of pairs — never a map: the order is what the model sees, and
Elixir maps have no order to preserve.
Keys may be atoms or strings; the answer comes back under the same kind.
A bare list of option names is accepted too, and each name becomes an option
with no description:
TypeSafeAPI.choice("Which team?", [:billing, :sales])
# same as
TypeSafeAPI.choice("Which team?", billing: nil, sales: nil)Give a Choice the full list rather than a shortlist, and add an other
option when the list might not cover every input.
instructions is optional; only criteria and the type are required. Pass
nil for a Choice whose options speak for themselves.
nil descriptions
A nil option description means the option name speaks for itself, and it
travels as JSON null: sales: nil is sent as "sales":null. This is the
one place the library sends a null rather than omitting the key — a JSON
object key must carry some value, and the spec's ChoiceQuestion.criteria
allows null explicitly. A nil instructions, by contrast, is left out of
the request entirely.
Limits
| limit | our validator | spec (priv/openapi.json, API 0.2.0) | source |
|---|---|---|---|
| min options | 1 | no bound (criteria is an unconstrained object) | local policy: an empty option set asks nothing |
| max options | 255 | no bound | local policy, matching a live-API 400 observed at 256 (see DESIGN.md) |
ChoiceQuestion.criteria in the OpenAPI spec has no minProperties or
maxProperties at all; both bounds here are this library's own policy, not
something read off the spec. A single-option Choice is a degenerate question
but a well-defined one, and criteria built at runtime can legitimately filter
down to one survivor, so only the empty set is rejected.
Summary
Functions
Builds a Choice question from a keyword list, a list of {key, description}
pairs, or a bare list of option names.
The type tag this question and its answer carry on the wire.
Types
@type option() :: {TypeSafeAPI.Keys.key(), TypeSafeAPI.Question.description() | nil}
@type t() :: %TypeSafeAPI.Question.Choice{ criteria: [option()], instructions: TypeSafeAPI.Question.instructions() }
Functions
@spec new(TypeSafeAPI.Question.instructions(), [option() | TypeSafeAPI.Keys.key()]) :: t()
Builds a Choice question from a keyword list, a list of {key, description}
pairs, or a bare list of option names.
A bare name is normalized to {name, nil}, so
new("Which?", [:billing, :sales]) and new("Which?", billing: nil, sales: nil)
build the same question.
Maps are not accepted: they have no order, and option order is what the
model sees. instructions is optional and may be nil.
@spec wire_type() :: String.t()
The type tag this question and its answer carry on the wire.