The three question types and the functions that validate and encode them.
Constructors never validate; validation happens once, locally, when a
question set is sent (TypeSafe.evaluate/4), so a Score with one level or a
Choice with one option fails fast with a :validation error value instead
of a round trip to the API. Only the three known types are accepted;
anything else is a local :validation error too.
Questions built at compile time (say, in a module attribute) can be checked
eagerly with validate!/1, which raises ArgumentError so the mistake shows
up at the line that made it.
questions given to TypeSafe.evaluate/4 may be a keyword list or a map of
id to question. normalize/1 turns either into an ordered [{id, question}]
list, which is the shape the rest of the typed layer works with.
Summary
Types
Anything the API accepts as a description: a string, map, or list.
Questions as the caller passes them.
Functions
Encodes a validated question to its JSON-ready wire map.
Encodes a normalized question list to the wire questions object,
preserving the caller's order.
Turns a keyword list or map of questions into an ordered [{id, question}]
list, validating every id and question.
Validates a single question struct.
Validates a question and raises ArgumentError if it is malformed.
Types
Anything the API accepts as a description: a string, map, or list.
@type input() :: [{TypeSafe.Keys.key(), t()}] | %{required(TypeSafe.Keys.key()) => t()}
Questions as the caller passes them.
@type t() :: TypeSafe.Question.Noul.t() | TypeSafe.Question.Choice.t() | TypeSafe.Question.Score.t()
Functions
Encodes a validated question to its JSON-ready wire map.
@spec encode_all([{TypeSafe.Keys.key(), t()}]) :: TypeSafe.JSON.OrderedObject.t()
Encodes a normalized question list to the wire questions object,
preserving the caller's order.
@spec normalize(input()) :: {:ok, [{TypeSafe.Keys.key(), t()}]} | {:error, TypeSafe.Error.t()}
Turns a keyword list or map of questions into an ordered [{id, question}]
list, validating every id and question.
Validates a single question struct.
Validates a question and raises ArgumentError if it is malformed.
Returns the question unchanged, so it can wrap a constructor:
@urgent TypeSafe.Question.validate!(TypeSafe.noul("Urgent?", true: "time-sensitive"))