pub struct Field {
pub name: String,
pub kind: InputKind,
pub required: bool,
pub validators: Vec<Box<dyn Validator>>,
pub options: Vec<(String, String)>,
}Expand description
A single form field: name + kind + validators. The field doesn’t
own its parsed value; validate reads from the form-data map and
pushes errors onto the accumulator.
Fields§
§name: String§kind: InputKind§required: bool§validators: Vec<Box<dyn Validator>>§options: Vec<(String, String)>(value, label) pairs for Select fields. Empty for every
other kind. For ModelChoice / ModelMultiChoice the options
are fetched async at render time (Task 6), so they stay empty
here too.
Implementations§
Source§impl Field
impl Field
Sourcepub fn text(name: impl Into<String>) -> Self
pub fn text(name: impl Into<String>) -> Self
New text field. Caller adds validators via builder methods.
Sourcepub fn regex(self, pattern: &str, message: impl Into<String>) -> Self
pub fn regex(self, pattern: &str, message: impl Into<String>) -> Self
Attach a regex-pattern validator to an existing field.
Composes with Required, MinLength, MaxLength, etc. —
the regex check fires after the others, so empty / missing
values surface the right “is required” error rather than
a confusing “doesn’t match pattern” error.
The pattern is compiled eagerly — an invalid regex panics at
construction time. The derive macro short-circuits this by
emitting the literal pattern, so a malformed
#[form(regex = "...")] surfaces as a panic in tests rather
than silently passing every input.
Use {field} in the message to interpolate the field name.
let f = Field::text("invoice_id")
.regex(r"^INV-\d{6}$", "{field} must look like `INV-123456`");Sourcepub fn phone(name: impl Into<String>) -> Self
pub fn phone(name: impl Into<String>) -> Self
New phone field — E.164 international format
(+<country><subscriber>, e.g. +14155551234). Catches the
common typo’d-phone cases (“07065”, “+0…”, letters mixed in,
dashes / spaces / parens that proper E.164 doesn’t allow).
Renders as <input type="tel"> so mobile browsers pop the
number keypad.
Soft-validation case (“accept anything phone-ish, even
without country code”): use Field::text + your own
.regex(...). The strict E.164 pattern here is the right
default because every form that asks for a phone number
SHOULD be storing them in E.164 (the only shape that
round-trips across providers / SMS gateways / address books).
Sourcepub fn url(name: impl Into<String>) -> Self
pub fn url(name: impl Into<String>) -> Self
New URL field — http(s) only, requires a host. Conservative:
ftp:// / mailto: / etc. get rejected so a form that
promises “URL” doesn’t persist a non-web scheme.
Sourcepub fn password(name: impl Into<String>) -> Self
pub fn password(name: impl Into<String>) -> Self
New password field. Identical validation rules to text; the
difference is the rendered <input type="password"> so the
browser masks input.
Sourcepub fn file(name: impl Into<String>) -> Self
pub fn file(name: impl Into<String>) -> Self
New file field — renders <input type="file">. One kind covers
both FileField and ImageField: the Form-side input is just a
file input (the admin’s image-preview is a column-widget
concern, not a form-input concern).
The submitted value is the opaque storage key the admin’s
multipart handler stored after the upload; there’s nothing to
validate about a key string beyond required/optional, so the
only validator is Required (dropped via .optional() for a
nullable field). Length / regex / format validators don’t apply.
Sourcepub fn integer(name: impl Into<String>) -> Self
pub fn integer(name: impl Into<String>) -> Self
New integer field. Validates that the value parses as i64.
Sourcepub fn float(name: impl Into<String>) -> Self
pub fn float(name: impl Into<String>) -> Self
New floating-point field. Renders as <input type="number">
(no step set; HTML’s default accepts decimals). Validates
only Required; the macro’s parse step is what catches
non-numeric input — the field-level validator would reject
integer literals which is the wrong shape for an f64 field.
Sourcepub fn boolean(name: impl Into<String>) -> Self
pub fn boolean(name: impl Into<String>) -> Self
New boolean field. Required-by-default would be wrong here
(HTML emits the field key only when the box is checked), so
boolean fields skip Required.
Sourcepub fn select(
name: impl Into<String>,
options: Vec<(String, String)>,
nullable: bool,
) -> Self
pub fn select( name: impl Into<String>, options: Vec<(String, String)>, nullable: bool, ) -> Self
New closed-set select field. options are (value, label)
pairs from a ChoiceField’s VALUES/LABELS. nullable
prepends a leading empty option and drops Required.
Sourcepub fn model_choice(
name: impl Into<String>,
target_table: &'static str,
label_field: Option<&'static str>,
pk_kind: PkKind,
nullable: bool,
) -> Self
pub fn model_choice( name: impl Into<String>, target_table: &'static str, label_field: Option<&'static str>, pk_kind: PkKind, nullable: bool, ) -> Self
New single-select FK field. options are fetched async at
render time (Task 6); at validate time only pk_kind is used to
parse the submitted id.
Sourcepub fn model_multi_choice(
name: impl Into<String>,
target_table: &'static str,
label_field: Option<&'static str>,
pk_kind: PkKind,
) -> Self
pub fn model_multi_choice( name: impl Into<String>, target_table: &'static str, label_field: Option<&'static str>, pk_kind: PkKind, ) -> Self
New multi-select M2M field. Options are fetched async at render time; submission is a list of child ids written to the junction table after the parent insert.
Sourcepub fn optional(self) -> Self
pub fn optional(self) -> Self
Mark the field as optional. The validate method
short-circuits when required is false and the value is
empty, so the Required validator (if any) doesn’t fire on
an empty optional field. Validators that wrap non-empty
values (MinLength, Pattern, …) still run when there’s
something to check.
Sourcepub fn min_length(self, n: usize) -> Self
pub fn min_length(self, n: usize) -> Self
Add a MinLength(n) validator. Builder method, returns self.
Sourcepub fn max_length(self, n: usize) -> Self
pub fn max_length(self, n: usize) -> Self
Add a MaxLength(n) validator. Builder method, returns self.
Sourcepub fn with_validator(self, v: impl Validator + 'static) -> Self
pub fn with_validator(self, v: impl Validator + 'static) -> Self
Add a custom validator. Named with_validator rather than
add so it doesn’t shadow std::ops::Add::add for clippy.
Sourcepub fn validate(&self, value: &str, errors: &mut ValidationErrors)
pub fn validate(&self, value: &str, errors: &mut ValidationErrors)
Run every validator over value. Errors push onto errors.
An empty value on a non-required field skips validation
entirely (an optional empty input is valid).
Sourcepub fn render_html(&self, value: &str) -> String
pub fn render_html(&self, value: &str) -> String
Render the field as a single HTML <input> element. The
value is the form’s prefill (empty for a fresh form, the
raw user input on a re-render after validation failed).
Sourcepub async fn render_html_async(&self, value: &str) -> String
pub async fn render_html_async(&self, value: &str) -> String
Async render entry point. ModelChoice / ModelMultiChoice
fetch their options first, then render the <select>; every
other kind defers to the sync render_html.
Auto Trait Implementations§
impl !RefUnwindSafe for Field
impl !UnwindSafe for Field
impl Freeze for Field
impl Send for Field
impl Sync for Field
impl Unpin for Field
impl UnsafeUnpin for Field
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
impl<A, B, T> HttpServerConnExec<A, B> for Twhere
B: Body,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Paint for Twhere
T: ?Sized,
impl<T> Paint for Twhere
T: ?Sized,
Source§fn fg(&self, value: Color) -> Painted<&T>
fn fg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the foreground set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like red() and
green(), which have the same functionality but are
pithier.
§Example
Set foreground color to white using fg():
use yansi::{Paint, Color};
painted.fg(Color::White);Set foreground color to white using white().
use yansi::Paint;
painted.white();Source§fn bright_black(&self) -> Painted<&T>
fn bright_black(&self) -> Painted<&T>
Source§fn bright_red(&self) -> Painted<&T>
fn bright_red(&self) -> Painted<&T>
Source§fn bright_green(&self) -> Painted<&T>
fn bright_green(&self) -> Painted<&T>
Source§fn bright_yellow(&self) -> Painted<&T>
fn bright_yellow(&self) -> Painted<&T>
Source§fn bright_blue(&self) -> Painted<&T>
fn bright_blue(&self) -> Painted<&T>
Source§fn bright_magenta(&self) -> Painted<&T>
fn bright_magenta(&self) -> Painted<&T>
Source§fn bright_cyan(&self) -> Painted<&T>
fn bright_cyan(&self) -> Painted<&T>
Source§fn bright_white(&self) -> Painted<&T>
fn bright_white(&self) -> Painted<&T>
Source§fn bg(&self, value: Color) -> Painted<&T>
fn bg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the background set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like on_red() and
on_green(), which have the same functionality but
are pithier.
§Example
Set background color to red using fg():
use yansi::{Paint, Color};
painted.bg(Color::Red);Set background color to red using on_red().
use yansi::Paint;
painted.on_red();Source§fn on_primary(&self) -> Painted<&T>
fn on_primary(&self) -> Painted<&T>
Source§fn on_magenta(&self) -> Painted<&T>
fn on_magenta(&self) -> Painted<&T>
Source§fn on_bright_black(&self) -> Painted<&T>
fn on_bright_black(&self) -> Painted<&T>
Source§fn on_bright_red(&self) -> Painted<&T>
fn on_bright_red(&self) -> Painted<&T>
Source§fn on_bright_green(&self) -> Painted<&T>
fn on_bright_green(&self) -> Painted<&T>
Source§fn on_bright_yellow(&self) -> Painted<&T>
fn on_bright_yellow(&self) -> Painted<&T>
Source§fn on_bright_blue(&self) -> Painted<&T>
fn on_bright_blue(&self) -> Painted<&T>
Source§fn on_bright_magenta(&self) -> Painted<&T>
fn on_bright_magenta(&self) -> Painted<&T>
Source§fn on_bright_cyan(&self) -> Painted<&T>
fn on_bright_cyan(&self) -> Painted<&T>
Source§fn on_bright_white(&self) -> Painted<&T>
fn on_bright_white(&self) -> Painted<&T>
Source§fn attr(&self, value: Attribute) -> Painted<&T>
fn attr(&self, value: Attribute) -> Painted<&T>
Enables the styling Attribute value.
This method should be used rarely. Instead, prefer to use
attribute-specific builder methods like bold() and
underline(), which have the same functionality
but are pithier.
§Example
Make text bold using attr():
use yansi::{Paint, Attribute};
painted.attr(Attribute::Bold);Make text bold using using bold().
use yansi::Paint;
painted.bold();Source§fn rapid_blink(&self) -> Painted<&T>
fn rapid_blink(&self) -> Painted<&T>
Source§fn quirk(&self, value: Quirk) -> Painted<&T>
fn quirk(&self, value: Quirk) -> Painted<&T>
Enables the yansi Quirk value.
This method should be used rarely. Instead, prefer to use quirk-specific
builder methods like mask() and
wrap(), which have the same functionality but are
pithier.
§Example
Enable wrapping using .quirk():
use yansi::{Paint, Quirk};
painted.quirk(Quirk::Wrap);Enable wrapping using wrap().
use yansi::Paint;
painted.wrap();Source§fn clear(&self) -> Painted<&T>
👎Deprecated since 1.0.1: renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
fn clear(&self) -> Painted<&T>
renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
Source§fn whenever(&self, value: Condition) -> Painted<&T>
fn whenever(&self, value: Condition) -> Painted<&T>
Conditionally enable styling based on whether the Condition value
applies. Replaces any previous condition.
See the crate level docs for more details.
§Example
Enable styling painted only when both stdout and stderr are TTYs:
use yansi::{Paint, Condition};
painted.red().on_yellow().whenever(Condition::STDOUTERR_ARE_TTY);