Skip to main content

Choice

Struct Choice 

Source
#[non_exhaustive]
pub struct Choice<'a> { pub value: &'a str, pub label: &'a str, pub unavailable: Option<&'a str>, pub detail: Option<&'a str>, pub chosen: bool, }
Expand description

One option offered by a field FieldKind::offers_options accepts.

Two strings, because the submitted value and the read label are different facts and every renderer that has tried to collapse them has had to un-collapse them later. makeover-webview invented this shape writing its form emitter and it is taken here unchanged; moving it down rather than re-deriving it is the point, since the second and third renderers were each going to arrive at a near-miss of it. #[non_exhaustive], which every type here that a renderer matches or builds carries. Without it a new member is a breaking change at every literal site in the tree.

Fields (Non-exhaustive)§

This struct is marked as non-exhaustive
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.
§value: &'a str

What is submitted.

§label: &'a str

What is read.

§unavailable: Option<&'a str>

Why it cannot be picked right now, when it cannot.

One member rather than an available: bool beside a reason, and the conflation is the point: an option greyed out with no explanation is a dead end the user cannot act on, and it is exactly the state the app that found this gap had to patch by hand with a line of prose under the control. Making the reason mandatory means the description cannot say the useless half.

The option stays in the list. Dropping it is what an app does today, and it costs the user the knowledge that the thing exists at all — audiofiles’ multi-sample mode appears on its own once a second sample is dropped, so a user who never sees it never learns what to drop.

Not Field::error, and not Field::hint. An error is about the answer and a hint is standing help for the whole question; this is about one option among several, which is the level neither of those reaches.

Not disabled-the-state. State::Disabled is about a whole field refusing to answer. This says the field is live and one of its answers is not available yet, which is a different sentence and the reason the tone rule matters here: the other options are still usable.

§detail: Option<&'a str>

The line under the label that says what picking this means.

A choice between three plans is a choice nobody can make from three names, and until this existed the description had nowhere to put the sentence that made it makeable. What the corpus did instead is the tell: four of the six measured sites fold it into the label — <strong>Public</strong>: Anyone can see this repository in MNW’s git settings, the same shape in its project-basics AI tier and its cart’s currency conversion, and Mislabeled (wrong AI tier or category) in its report modal. The described screens do it too, in miniature: Every 15 minutes (recommended), Reference samples in place (loose-files mode). One fact, six spellings, no member.

§Where it goes is the host’s, and the rule already exists

This is unavailable’s question met a third time and it takes the same answer, which is the strongest evidence one member is right rather than two. A radio group has room and gives the line its own element beside the label. A <select>’s option takes no elements, no second line and no title a keyboard reaches, so the line runs into the option’s own text — exactly as a precondition does, and as a theme’s contrast badge does in brackets. A terminal has rows and puts it on one under the option.

§Not a price, and that is a measurement rather than a preference

The site that asked for this is MNW’s fee calculator, whose tier cards carry a name, a price and a description, so a second member for the price was on the table. It loses on the count: the tree’s other three priced tier lists — project.html, project_paywall.html, index.html — are not option lists at all. Each card carries its own submit, which makes it a region with a heading, a fact and an act, and it is sayable already. So a price member would have exactly one consumer, and it would mean this crate growing a money type it does not have: Unit is a time axis, and every amount in the described tree is text.

The price therefore leads the line: $24/mo. 2GB/file, 100GB total. Fits audio, plugins, binaries. What would reopen it is a second priced option list, not a judgement about how that reads.

§What it is not

Not unavailable, which says the option cannot be picked. This says what it means to pick it, and the two are drawn together on an option that carries both: the description that says a tier is out of stock and what the tier is has said two things.

Not Field::hint, which is standing help for the whole question, and not markup. One line of plain text, for Candidate::detail’s reason: an option list is a place a renderer lays out, and a description that put a block in one would be handing every host a layout problem for the benefit of one.

§chosen: bool

Whether this is the option currently chosen.

The alternative, and what every renderer here did before this member existed, is to compare the field’s current value against each option’s own. That reads the same and is not the same: it states which option is marked ONCE, at the field, and leaves each option to work out whether the sentence is about it. A description whose data already knows per row – a theme list where each theme carries selected – then has to collapse that to one string for the renderer to re-derive, which is one fact stated twice.

§Never both

An option list either marks itself here or is matched against the field’s value, and a description that does both has said one thing two ways, which is how the two drift. quasi-declare refuses the pair at compile time. This crate cannot: it is handed a list and a value with no record of which spelling built them, so a renderer marks an option whose chosen is set OR whose value matches, and a caller that sets both gets both marked.

§What it buys, beyond saying it once

It is the only form a compiled template can carry. A residual holds one body per loop, so “exactly one row differs” cannot be a property of the row body when the difference is decided by a comparison the body does not make. Said here it is a branch inside the row, which is a shape a residual has.

Implementations§

Source§

impl<'a> Choice<'a>

Source

pub const fn plain(value: &'a str) -> Self

An option whose submitted value is also its label.

Source

pub const fn new(value: &'a str, label: &'a str) -> Self

An option that submits one string and reads as another.

A constructor rather than a literal, which is what #[non_exhaustive] costs and buys: outside this crate the struct cannot be built by naming its members, so every call site goes through here and the next member added breaks none of them.

Source

pub const fn unless(self, reason: &'a str) -> Self

The same option, not pickable yet, and why.

Builder-shaped because the reason is the rare case: 39 of the 40 option sites measured across the tree do not have one.

Source

pub const fn detailing(self, detail: &'a str) -> Self

The same option, with the line that says what picking it means.

Builder-shaped for unless’s reason, and it is the commoner of the two: six measured sites want this and one wants a precondition. See detail.

Source

pub const fn chosen(self) -> Self

The same option, marked as the one currently chosen.

See chosen. Builder-shaped like the other two, and for the same reason: the marked option is one row of a list where every other row is not.

Source

pub const fn available(&self) -> bool

Whether the option can be picked right now.

The predicate a renderer branches on, so that “unavailable” is read as one condition in one place rather than as unavailable.is_some() at three renderers, one of which will invert it.

Trait Implementations§

Source§

impl<'a> Clone for Choice<'a>

Source§

fn clone(&self) -> Choice<'a>

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<'a> Copy for Choice<'a>

Source§

impl<'a> Debug for Choice<'a>

Source§

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

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

impl<'a> Eq for Choice<'a>

Source§

impl<'a> Hash for Choice<'a>

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<'a> PartialEq for Choice<'a>

Source§

fn eq(&self, other: &Choice<'a>) -> bool

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

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

Inequality operator !=. Read more
Source§

impl<'a> StructuralPartialEq for Choice<'a>

Auto Trait Implementations§

§

impl<'a> Freeze for Choice<'a>

§

impl<'a> RefUnwindSafe for Choice<'a>

§

impl<'a> Send for Choice<'a>

§

impl<'a> Sync for Choice<'a>

§

impl<'a> Unpin for Choice<'a>

§

impl<'a> UnsafeUnpin for Choice<'a>

§

impl<'a> UnwindSafe for Choice<'a>

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 = !

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

fn try_from(value: U) -> Result<T, !>

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.