Skip to main content

FieldKind

Enum FieldKind 

Source
#[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
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

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.

§

Email

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

Source

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.

Source

pub const fn visible(self) -> bool

Whether the field is drawn at all.

Source

pub const fn confidential(self) -> bool

Whether the value must be kept out of logs and diagnostics.

Source

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.

Source

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.

Trait Implementations§

Source§

impl Clone for FieldKind

Source§

fn clone(&self) -> FieldKind

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Copy for FieldKind

Source§

impl Debug for FieldKind

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Eq for FieldKind

Source§

impl Hash for FieldKind

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl PartialEq for FieldKind

Source§

fn eq(&self, other: &FieldKind) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for FieldKind

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.