#[non_exhaustive]pub enum FieldKind {
Show 14 variants
Text,
Secret,
Number,
Email,
Url,
Tel,
Date,
DateTime,
Textarea,
Select,
Radio,
Checkbox,
File,
Hidden,
}Expand description
What kind of value a form field takes.
The union of the two vocabularies that diverged, which is what triggered
this crate. They have since converged on their own: both apps now have a
renderFormField emitting the same anatomy, and what is left differing is
the kind set, the error shape, and whether the return is a string or a node.
Validation is deliberately absent. Neither app has a shared story (goingson
validates after collecting the form data, with per-field transform hooks;
Balanced Breakfast has required and nothing else), and a schema that
describes fields but not constraints acquires a constraint layer per app,
which is exactly how the current divergence started. Naming it absent is a
decision; leaving it unmentioned would not be.
#[non_exhaustive] for the reason Fill is: renderers match on this and
the set keeps growing, so growth must not be a lockstep event. Email, Url
and Tel arriving in 0.5.0 is the second growth in two releases.
Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
Text
A single line of text.
Secret
A single line of text that must never be echoed, logged or round-tripped through anything that might persist it.
Number
A number.
An email address.
Distinct from Text because the distinction is not
decoration: a webview renderer emits type="email", which on a touch
device changes the keyboard that appears and turns on the platform’s own
validation. goingson ships to iOS, so collapsing this into text costs a
keyboard with no @ on it.
Added 0.5.0, from goingson’s contact form.
Url
A URL. Same reasoning as Email.
Added 0.5.0, from goingson’s contact-social and contact-feed forms.
Tel
A telephone number. Same reasoning as Email, and the
clearest case of it: the keyboard is a numeric pad rather than letters.
Added 0.5.0, from goingson’s contact-phone form.
Date
A calendar day, with no time of day in it.
Email’s argument, and it carries further: a webview
emits type="date", which is a native picker, the platform’s own
validation, and on a touch device the date keyboard. Described as
Text with a hint reading “YYYY-MM-DD”, all three are
lost and the hint is doing the platform’s job in prose.
The membership test passes on every host without stretching: a webview and a Tauri app emit the input, egui has a date picker, a terminal prompts for a day and can validate it, a CLI takes an argument.
§The value is ISO 8601, YYYY-MM-DD
Named here rather than left to each host, because a host that picks
differently sends a server something it parses differently, and the
failure is silent and per-host. It is <input type="date">’s own wire
format, so the webview renderer owes nothing to honour it and the other
hosts have one spelling to meet. DATE_FORMAT is the constant, and a
test asserts this doc and that constant agree.
Added 0.15.0, from the MNW server’s git access-token expiry
(user_ssh_keys_tab.html) and six further sites across the server and
goingson.
DateTime
A calendar day and a time of day together.
Apart from Date because the question is different rather
than more precise: “which day does this expire” and “at what moment does
this publish” are asked by different screens and answered by different
controls. A webview emits type="datetime-local" for one and
type="date" for the other, and a host that collapsed them would ask
half the tree for a precision it does not want.
Both arrived together on measurement rather than on symmetry: 13 sites
of each across the MNW server and goingson, and zero of time,
month or week, which is why those are not here. A member added for a
case nobody has is a member designed against nothing, which is
File’s reasoning about accept applied to a whole
member.
§The value is YYYY-MM-DDTHH:MM, local, with no zone
<input type="datetime-local">’s own format, and the “local” is the
load-bearing half: the value carries no offset and no Z, so the moment
it names is only fixed once something supplies a zone. That is the app’s
business and not the description’s. Seconds are absent, which is the
browser’s own default and is left as the rule rather than restated as a
constraint. DATETIME_FORMAT is the constant.
Field::min and Field::max already take “the host’s own spelling
of a bound”, so a floor of not in the past needs nothing new here: it
is a string in this same format.
Added 0.15.0, from goingson’s snooze picker and day planner and the MNW server’s publish-at fields.
Textarea
Several lines of text.
Select
One of a fixed set, offered behind a control that shows one at a time.
Radio
One of a fixed set, with every option on screen at once.
Not a presentation of Select, which is the reading to
resist: what differs is a property of the question. A choice that is
consequential or irreversible has to be readable without opening
anything, because a closed control shows one option and hides the rest,
and the one it shows is whichever was current before the user had read
the alternatives. audiofiles asks whether a library copies samples into
its store or references them where they lie — which cannot be changed
afterwards — and had already promoted that out of a checkbox by hand,
with a comment giving this reason, before the description could say it.
It was described here at 0.8.1 as “the one HTML input type this enum was
missing”, which was not true then and is not true now: file arrived at
0.11.0 and date and datetime-local at 0.15.0. Everything here is
still an <input type=...>, a <select> or a <textarea>, and the way
this enum grows is by a site being measured rather than by a list being
completed, so “the last one” is not a claim it should make again.
Added 0.8.1, from audiofiles’ Add Library form.
Checkbox
On or off.
File
A file the user picks from wherever the host keeps files.
Added 0.11.0, 844b5ae0, from goingson’s project-dashboard attachments
column. It was filed as a router finding — a control whose destination is
a host capability rather than an address — and splitting it is what made
it two answers instead of one member satisfying neither. Opening a file
is a one-way handoff and needs no new API. Picking one returns a value
into a write, which is a form concern, which is this.
The membership test passes on every host and not by a stretch: a Tauri
app opens a native picker, a server renders <input type="file">, a
terminal prompts for a path, a CLI takes an argument. That is closer to
Email, which exists because it changes the keyboard,
than to anything bespoke.
It carries no accepted-types list and no multiple flag, and that is
measured rather than deferred: accept appears at zero sites in either
app. A member added for a case nobody has is a member designed against
nothing.
Hidden
Carried through the form and never shown.
Implementations§
Source§impl FieldKind
impl FieldKind
Sourcepub const fn temporal(self) -> bool
pub const fn temporal(self) -> bool
Whether the value the kind takes is a moment rather than a string.
Named once here for the reason offers_options
is: two kinds answer yes, and a host that has to parse or format a value
needs to ask without spelling the pair out at each renderer. A third
temporal kind should land here and nowhere else.
The format each one takes is DATE_FORMAT and DATETIME_FORMAT.
Sourcepub const fn confidential(self) -> bool
pub const fn confidential(self) -> bool
Whether the value must be kept out of logs and diagnostics.
Sourcepub const fn labels_itself(self) -> bool
pub const fn labels_itself(self) -> bool
Where the field’s own label sits.
A checkbox labels itself on the right of the box; everything else takes a label above. Both webview apps already do this and both special-case it inline, which is the tell that it belongs in the description.
A Radio is not one of them, and the near-miss is worth
naming: its options each label themselves, but the field still asks a
question above them, so the group takes a label like everything else.
Sourcepub const fn offers_options(self) -> bool
pub const fn offers_options(self) -> bool
Whether the kind reads Field::options.
Two kinds do, so the pair is named once here rather than spelled out at
each renderer and again in Field::options’ own doc, where “every
kind but Select” was true for exactly one release. A third
option-taking kind should land here and nowhere else.