Rate the state along an ordered scale you describe in steps.
TypeSafeAPI.score("How frustrated is the customer?", ["Calm", "Frustrated", "Very angry"])TypeSafe's advice: ask for one snap judgment per question, and write the levels in order from low to high; this library enforces two at minimum and ten at most as local policy (see "Limits" below).
levels is an ordered list from the low end of the scale to the high end.
This library requires at least two levels and caps a Score at ten: a single
level cannot produce a meaningful score, and the live API rejects eleven
levels with a 400 (see DESIGN.md). Each level is a description: a string,
or a map or list when a level needs structure.
A level may also be given as {label, description}. The label is a short
name you want back in the answer (TypeSafeAPI.Answer.Score.label), and the
pair is sent to the API as a structured level:
{"Very angry", "Threats to cancel, profanity, all caps"}
#=> {"label": "Very angry", "description": "Threats to cancel, ..."}The same structured shape written out by hand,
%{"label" => "Very angry", "description" => "..."}, is recognized as a
labelled level too, so a level that round-trips through the wire legend
still reports its label rather than an inspect/1 of the map.
Labels are strings. Atom labels — [calm: "...", angry: "..."], the shape
TypeSafeAPI.choice/2 takes — are not accepted yet; write the label as a
string for now.
Every level has a string label in the answer. A plain string level is its
own label; a structured level without one gets a truncated inspect/1 of
itself, which is fine for logs but not for display, so give structured
levels a label when the label matters. Labels must be distinct and non-empty:
the answer's levels list is keyed by label, so two levels sharing one name
cannot be told apart.
Limits
| limit | our validator | spec (priv/openapi.json, API 0.2.0) | source |
|---|---|---|---|
| min levels | 2 | minItems: 1 | local policy: a one-level score is meaningless |
| max levels | 10 | no bound | local policy, matching a live-API 400 observed at 11 (see DESIGN.md) |
ScoreQuestion.criteria in the OpenAPI spec requires only minItems: 1 and
sets no maximum; both bounds here are this library's own policy, tighter
than what the spec itself requires.
Summary
Functions
The description sent to the API for a level, without any label wrapper.
The string label for a level: the label of a {label, description} pair or
of a %{"label" => ...} map, a string level itself, or a truncated
inspect/1 of any other structured level.
Builds a Score question.
The type tag this question and its answer carry on the wire.
Types
@type level() :: TypeSafeAPI.Question.description() | {String.t(), TypeSafeAPI.Question.description()}
@type t() :: %TypeSafeAPI.Question.Score{ instructions: TypeSafeAPI.Question.instructions(), levels: [level()] }
Functions
@spec description(level()) :: TypeSafeAPI.Question.description()
The description sent to the API for a level, without any label wrapper.
The string label for a level: the label of a {label, description} pair or
of a %{"label" => ...} map, a string level itself, or a truncated
inspect/1 of any other structured level.
@spec new(TypeSafeAPI.Question.instructions(), [level()]) :: t()
Builds a Score question.
instructions is optional and may be nil; only the levels are required.
@spec wire_type() :: String.t()
The type tag this question and its answer carry on the wire.