Trait rocket::form::FromFormField [−][src]
pub trait FromFormField<'v>: Send + Sized { fn from_value(field: ValueField<'v>) -> Result<'v, Self> { ... } #[must_use] fn from_data<'life0, 'async_trait>(
field: DataField<'v, 'life0>
) -> Pin<Box<dyn Future<Output = Result<'v, Self>> + Send + 'async_trait>>
where
'v: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait, { ... } fn default() -> Option<Self> { ... } }
Expand description
Implied form guard (FromForm
) for parsing a single form field.
Types that implement FromFormField
automatically implement FromForm
via a blanket implementation. As such, all FromFormField
types are form
guards and can appear as the type of values in derived FromForm
struct
fields:
#[derive(FromForm)] struct Person<'r> { name: &'r str, age: u16 }
Deriving
FromFormField
can be derived for C-like enums, where the generated
implementation case-insensitively parses fields with values equal to the
name of the variant or the value in field(value = "...")
.
/// Fields with value `"simple"` parse as `Kind::Simple`. Fields with value /// `"fancy"` parse as `Kind::SoFancy`. #[derive(FromFormField)] enum Kind { Simple, #[field(value = "fancy")] SoFancy, }
Provided Implementations
See FromForm
for a list
of all form guards, including those implemented via FromFormField
.
Implementing
Implementing FromFormField
requires implementing one or both of
from_value
or from_data
, depending on whether the type can be parsed
from a value field (text) and/or streaming binary data. Typically, a value
can be parsed from either, either directly or by using request-local cache
as an intermediary, and parsing from both should be preferred when sensible.
FromFormField
is an async trait, so implementations must be decorated with
an attribute of #[rocket::async_trait]
:
use rocket::form::{self, FromFormField, DataField, ValueField}; #[rocket::async_trait] impl<'r> FromFormField<'r> for MyType { fn from_value(field: ValueField<'r>) -> form::Result<'r, Self> { todo!("parse from a value or use default impl") } async fn from_data(field: DataField<'r, '_>) -> form::Result<'r, Self> { todo!("parse from a value or use default impl") } }
Example
The following example parses a custom Person
type with the format
$name:$data
, where $name
is expected to be string and data
is expected
to be any slice of bytes.
use rocket::data::ToByteUnit; use rocket::form::{self, FromFormField, DataField, ValueField}; use memchr::memchr; struct Person<'r> { name: &'r str, data: &'r [u8] } #[rocket::async_trait] impl<'r> FromFormField<'r> for Person<'r> { fn from_value(field: ValueField<'r>) -> form::Result<'r, Self> { match field.value.find(':') { Some(i) => Ok(Person { name: &field.value[..i], data: field.value[(i + 1)..].as_bytes() }), None => Err(form::Error::validation("does not contain ':'"))? } } async fn from_data(field: DataField<'r, '_>) -> form::Result<'r, Self> { // Retrieve the configured data limit or use `256KiB` as default. let limit = field.request.limits() .get("person") .unwrap_or(256.kibibytes()); // Read the capped data stream, returning a limit error as needed. let bytes = field.data.open(limit).into_bytes().await?; if !bytes.is_complete() { Err((None, Some(limit)))?; } // Store the bytes in request-local cache and split at ':'. let bytes = bytes.into_inner(); let bytes = rocket::request::local_cache!(field.request, bytes); let (raw_name, data) = match memchr(b':', bytes) { Some(i) => (&bytes[..i], &bytes[(i + 1)..]), None => Err(form::Error::validation("does not contain ':'"))? }; // Try to parse the name as UTF-8 or return an error if it fails. let name = std::str::from_utf8(raw_name)?; Ok(Person { name, data }) } } use rocket::form::{Form, FromForm}; // The type can be used directly, if only one field is expected... #[post("/person", data = "<person>")] fn person(person: Form<Person<'_>>) { /* ... */ } // ...or as a named field in another form guard... #[derive(FromForm)] struct NewPerson<'r> { person: Person<'r> } #[post("/person", data = "<person>")] fn new_person(person: Form<NewPerson<'_>>) { /* ... */ }
Provided methods
fn from_value(field: ValueField<'v>) -> Result<'v, Self>
[src]
fn from_value(field: ValueField<'v>) -> Result<'v, Self>
[src]Parse a value of T
from a form value field.
The default implementation returns an error of
ValueField::unexpected()
.
Parse a value of T
from a form data field.
The default implementation returns an error of
DataField::unexpected()
.
Returns a default value, if any exists, to be used during lenient parsing when the form field is missing.
A return value of None
means that field is required to exist and parse
successfully, always. A return value of Some(default)
means that
default
should be used when a field is missing.
The default implementation returns None
.
Implementations on Foreign Types
Implementors
uuid
only.json
only.msgpack
only.