Trait rocket::data::FromData [−][src]
Trait implemented by data guards to derive a value from request body data.
Data Guards
A data guard is a guard that operates on a request’s body data. Data guards
validate and parse request body data via implementations of FromData
. In
other words, a type is a data guard iff it implements FromData
.
Data guards are the target of the data
route attribute parameter:
#[post("/submit", data = "<var>")] fn submit(var: DataGuard) { /* ... */ }
A route can have at most one data guard. Above, var
is used as the
argument name for the data guard type DataGuard
. When the submit
route
matches, Rocket will call the FromData
implementation for the type T
.
The handler will only be called if the guard returns successfully.
Async Trait
FromData
is an async trait. Implementations of FromData
must be
decorated with an attribute of #[rocket::async_trait]
:
use rocket::request::Request; use rocket::data::{self, Data, FromData}; #[rocket::async_trait] impl<'r> FromData<'r> for MyType { type Error = MyError; async fn from_data(req: &'r Request<'_>, data: Data) -> data::Outcome<Self, MyError> { /* .. */ } }
Example
Say that you have a custom type, Person
:
struct Person<'r> { name: &'r str, age: u16 }
Person
has a custom serialization format, so the built-in Json
type
doesn’t suffice. The format is <name>:<age>
with Content-Type: application/x-person
. You’d like to use Person
as a data guard, so that
you can retrieve it directly from a client’s request body:
#[post("/person", data = "<person>")] fn person(person: Person<'_>) -> &'static str { "Saved the new person to the database!" }
A FromData
implementation for such a type might look like:
use rocket::request::{self, Request}; use rocket::data::{self, Data, FromData, ToByteUnit}; use rocket::http::{Status, ContentType}; enum Error { TooLarge, NoColon, InvalidAge, Io(std::io::Error), } #[rocket::async_trait] impl<'r> FromData<'r> for Person<'r> { type Error = Error; async fn from_data(req: &'r Request<'_>, data: Data) -> data::Outcome<Self, Error> { use Error::*; use rocket::outcome::Outcome::*; // Ensure the content type is correct before opening the data. let person_ct = ContentType::new("application", "x-person"); if req.content_type() != Some(&person_ct) { return Forward(data); } // Use a configured limit with name 'person' or fallback to default. let limit = req.limits().get("person").unwrap_or(256.bytes()); // Read the data into a string. let string = match data.open(limit).into_string().await { Ok(string) if string.is_complete() => string.into_inner(), Ok(_) => return Failure((Status::PayloadTooLarge, TooLarge)), Err(e) => return Failure((Status::InternalServerError, Io(e))), }; // We store `string` in request-local cache for long-lived borrows. let string = request::local_cache!(req, string); // Split the string into two pieces at ':'. let (name, age) = match string.find(':') { Some(i) => (&string[..i], &string[(i + 1)..]), None => return Failure((Status::UnprocessableEntity, NoColon)), }; // Parse the age. let age: u16 = match age.parse() { Ok(age) => age, Err(_) => return Failure((Status::UnprocessableEntity, InvalidAge)), }; Success(Person { name, age }) } } // The following routes now typecheck... #[post("/person", data = "<person>")] fn person(person: Person<'_>) { /* .. */ } #[post("/person", data = "<person>")] fn person2(person: Result<Person<'_>, Error>) { /* .. */ } #[post("/person", data = "<person>")] fn person3(person: Option<Person<'_>>) { /* .. */ } #[post("/person", data = "<person>")] fn person4(person: Person<'_>) -> &str { // Note that this is only possible because the data in `person` live // as long as the request through request-local cache. person.name }
Associated Types
Loading content...Required methods
#[must_use]fn from_data<'life0, 'async_trait>(
req: &'r Request<'life0>,
data: Data
) -> Pin<Box<dyn Future<Output = Outcome<Self, Self::Error>> + Send + 'async_trait>> where
'r: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait,
[src]
req: &'r Request<'life0>,
data: Data
) -> Pin<Box<dyn Future<Output = Outcome<Self, Self::Error>> + Send + 'async_trait>> where
'r: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait,
Asynchronously validates, parses, and converts an instance of Self
from the incoming request body data.
If validation and parsing succeeds, an outcome of Success
is returned.
If the data is not appropriate given the type of Self
, Forward
is
returned. If parsing fails, Failure
is returned.
Implementations on Foreign Types
impl<'r> FromData<'r> for String
[src]
type Error = <Capped<Self> as FromData<'r>>::Error
fn from_data<'life0, 'async_trait>(
r: &'r Request<'life0>,
d: Data
) -> Pin<Box<dyn Future<Output = Outcome<Self, Self::Error>> + Send + 'async_trait>> where
'r: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait,
[src]
r: &'r Request<'life0>,
d: Data
) -> Pin<Box<dyn Future<Output = Outcome<Self, Self::Error>> + Send + 'async_trait>> where
'r: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait,
impl<'r> FromData<'r> for &'r str
[src]
type Error = <Capped<Self> as FromData<'r>>::Error
fn from_data<'life0, 'async_trait>(
r: &'r Request<'life0>,
d: Data
) -> Pin<Box<dyn Future<Output = Outcome<Self, Self::Error>> + Send + 'async_trait>> where
'r: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait,
[src]
r: &'r Request<'life0>,
d: Data
) -> Pin<Box<dyn Future<Output = Outcome<Self, Self::Error>> + Send + 'async_trait>> where
'r: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait,
impl<'impl0, 'r> FromData<'r> for Cow<'impl0, str>
[src]
type Error = <Capped<Self> as FromData<'r>>::Error
fn from_data<'life0, 'async_trait>(
r: &'r Request<'life0>,
d: Data
) -> Pin<Box<dyn Future<Output = Outcome<Self, Self::Error>> + Send + 'async_trait>> where
'r: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait,
[src]
r: &'r Request<'life0>,
d: Data
) -> Pin<Box<dyn Future<Output = Outcome<Self, Self::Error>> + Send + 'async_trait>> where
'r: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait,
impl<'r> FromData<'r> for &'r [u8]
[src]
type Error = <Capped<Self> as FromData<'r>>::Error
fn from_data<'life0, 'async_trait>(
r: &'r Request<'life0>,
d: Data
) -> Pin<Box<dyn Future<Output = Outcome<Self, Self::Error>> + Send + 'async_trait>> where
'r: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait,
[src]
r: &'r Request<'life0>,
d: Data
) -> Pin<Box<dyn Future<Output = Outcome<Self, Self::Error>> + Send + 'async_trait>> where
'r: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait,
impl<'r> FromData<'r> for Vec<u8>
[src]
type Error = <Capped<Self> as FromData<'r>>::Error
fn from_data<'life0, 'async_trait>(
r: &'r Request<'life0>,
d: Data
) -> Pin<Box<dyn Future<Output = Outcome<Self, Self::Error>> + Send + 'async_trait>> where
'r: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait,
[src]
r: &'r Request<'life0>,
d: Data
) -> Pin<Box<dyn Future<Output = Outcome<Self, Self::Error>> + Send + 'async_trait>> where
'r: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait,
impl<'r, T: FromData<'r> + 'r> FromData<'r> for Result<T, T::Error>
[src]
type Error = Infallible
fn from_data<'life0, 'async_trait>(
req: &'r Request<'life0>,
data: Data
) -> Pin<Box<dyn Future<Output = Outcome<Result<T, <T as FromData<'r>>::Error>, Self::Error>> + Send + 'async_trait>> where
'r: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait,
[src]
req: &'r Request<'life0>,
data: Data
) -> Pin<Box<dyn Future<Output = Outcome<Result<T, <T as FromData<'r>>::Error>, Self::Error>> + Send + 'async_trait>> where
'r: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait,
impl<'r, T: FromData<'r>> FromData<'r> for Option<T>
[src]
type Error = Infallible
fn from_data<'life0, 'async_trait>(
req: &'r Request<'life0>,
data: Data
) -> Pin<Box<dyn Future<Output = Outcome<Self, Self::Error>> + Send + 'async_trait>> where
'r: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait,
[src]
req: &'r Request<'life0>,
data: Data
) -> Pin<Box<dyn Future<Output = Outcome<Self, Self::Error>> + Send + 'async_trait>> where
'r: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait,
Implementors
impl<'impl0, 'r> FromData<'r> for TempFile<'impl0>
[src]
type Error = <Capped<Self> as FromData<'r>>::Error
fn from_data<'life0, 'async_trait>(
r: &'r Request<'life0>,
d: Data
) -> Pin<Box<dyn Future<Output = Outcome<Self, Self::Error>> + Send + 'async_trait>> where
'r: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait,
[src]
r: &'r Request<'life0>,
d: Data
) -> Pin<Box<dyn Future<Output = Outcome<Self, Self::Error>> + Send + 'async_trait>> where
'r: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait,
impl<'impl0, 'r> FromData<'r> for Capped<TempFile<'impl0>>
[src]
type Error = Error
fn from_data<'life0, 'async_trait>(
req: &'r Request<'life0>,
data: Data
) -> Pin<Box<dyn Future<Output = Outcome<Self, Self::Error>> + Send + 'async_trait>> where
'r: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait,
[src]
req: &'r Request<'life0>,
data: Data
) -> Pin<Box<dyn Future<Output = Outcome<Self, Self::Error>> + Send + 'async_trait>> where
'r: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait,
impl<'impl0, 'r> FromData<'r> for Capped<Cow<'impl0, str>>
[src]
type Error = Error
fn from_data<'life0, 'async_trait>(
req: &'r Request<'life0>,
data: Data
) -> Pin<Box<dyn Future<Output = Outcome<Self, Self::Error>> + Send + 'async_trait>> where
'r: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait,
[src]
req: &'r Request<'life0>,
data: Data
) -> Pin<Box<dyn Future<Output = Outcome<Self, Self::Error>> + Send + 'async_trait>> where
'r: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait,
impl<'r> FromData<'r> for &'r RawStr
[src]
type Error = <Capped<Self> as FromData<'r>>::Error
fn from_data<'life0, 'async_trait>(
r: &'r Request<'life0>,
d: Data
) -> Pin<Box<dyn Future<Output = Outcome<Self, Self::Error>> + Send + 'async_trait>> where
'r: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait,
[src]
r: &'r Request<'life0>,
d: Data
) -> Pin<Box<dyn Future<Output = Outcome<Self, Self::Error>> + Send + 'async_trait>> where
'r: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait,
impl<'r> FromData<'r> for Capped<&'r str>
[src]
type Error = Error
fn from_data<'life0, 'async_trait>(
req: &'r Request<'life0>,
data: Data
) -> Pin<Box<dyn Future<Output = Outcome<Self, Self::Error>> + Send + 'async_trait>> where
'r: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait,
[src]
req: &'r Request<'life0>,
data: Data
) -> Pin<Box<dyn Future<Output = Outcome<Self, Self::Error>> + Send + 'async_trait>> where
'r: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait,
impl<'r> FromData<'r> for Capped<&'r RawStr>
[src]
type Error = Error
fn from_data<'life0, 'async_trait>(
req: &'r Request<'life0>,
data: Data
) -> Pin<Box<dyn Future<Output = Outcome<Self, Self::Error>> + Send + 'async_trait>> where
'r: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait,
[src]
req: &'r Request<'life0>,
data: Data
) -> Pin<Box<dyn Future<Output = Outcome<Self, Self::Error>> + Send + 'async_trait>> where
'r: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait,
impl<'r> FromData<'r> for Capped<&'r [u8]>
[src]
type Error = Error
fn from_data<'life0, 'async_trait>(
req: &'r Request<'life0>,
data: Data
) -> Pin<Box<dyn Future<Output = Outcome<Self, Self::Error>> + Send + 'async_trait>> where
'r: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait,
[src]
req: &'r Request<'life0>,
data: Data
) -> Pin<Box<dyn Future<Output = Outcome<Self, Self::Error>> + Send + 'async_trait>> where
'r: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait,
impl<'r> FromData<'r> for Capped<String>
[src]
type Error = Error
fn from_data<'life0, 'async_trait>(
req: &'r Request<'life0>,
data: Data
) -> Pin<Box<dyn Future<Output = Outcome<Self, Self::Error>> + Send + 'async_trait>> where
'r: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait,
[src]
req: &'r Request<'life0>,
data: Data
) -> Pin<Box<dyn Future<Output = Outcome<Self, Self::Error>> + Send + 'async_trait>> where
'r: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait,
impl<'r> FromData<'r> for Capped<Vec<u8>>
[src]
type Error = Error
fn from_data<'life0, 'async_trait>(
req: &'r Request<'life0>,
data: Data
) -> Pin<Box<dyn Future<Output = Outcome<Self, Self::Error>> + Send + 'async_trait>> where
'r: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait,
[src]
req: &'r Request<'life0>,
data: Data
) -> Pin<Box<dyn Future<Output = Outcome<Self, Self::Error>> + Send + 'async_trait>> where
'r: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait,
impl<'r> FromData<'r> for Data
[src]
type Error = Infallible
fn from_data<'life0, 'async_trait>(
__arg0: &'r Request<'life0>,
data: Data
) -> Pin<Box<dyn Future<Output = Outcome<Self, Self::Error>> + Send + 'async_trait>> where
'r: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait,
[src]
__arg0: &'r Request<'life0>,
data: Data
) -> Pin<Box<dyn Future<Output = Outcome<Self, Self::Error>> + Send + 'async_trait>> where
'r: 'async_trait,
'life0: 'async_trait,
Self: 'async_trait,