Allow implementations of FromData to return a Future that borrows from the request.

This commit is contained in:
Jeb Rosen 2019-12-10 16:34:29 -08:00 committed by Sergio Benitez
parent 468f4d9314
commit cc3298c3e4
5 changed files with 35 additions and 36 deletions

View File

@ -135,9 +135,9 @@ impl<'a, T: Deserialize<'a>> FromData<'a> for Json<T> {
type Owned = String;
type Borrowed = str;
fn transform(r: &Request<'_>, d: Data) -> TransformFuture<'a, Self::Owned, Self::Error> {
let size_limit = r.limits().get("json").unwrap_or(LIMIT);
fn transform<'r>(r: &'r Request<'_>, d: Data) -> TransformFuture<'r, Self::Owned, Self::Error> {
Box::pin(async move {
let size_limit = r.limits().get("json").unwrap_or(LIMIT);
let mut s = String::with_capacity(512);
let mut reader = d.open().take(size_limit);
match reader.read_to_string(&mut s).await {
@ -147,7 +147,7 @@ impl<'a, T: Deserialize<'a>> FromData<'a> for Json<T> {
})
}
fn from_data(_: &Request<'_>, o: Transformed<'a, Self>) -> FromDataFuture<'a, Self, Self::Error> {
fn from_data(_: &'a Request<'_>, o: Transformed<'a, Self>) -> FromDataFuture<'a, Self, Self::Error> {
Box::pin(async move {
let string = try_outcome!(o.borrowed());
match serde_json::from_str(&string) {

View File

@ -120,10 +120,9 @@ impl<'a, T: Deserialize<'a>> FromData<'a> for MsgPack<T> {
type Owned = Vec<u8>;
type Borrowed = [u8];
fn transform(r: &Request<'_>, d: Data) -> TransformFuture<'a, Self::Owned, Self::Error> {
let size_limit = r.limits().get("msgpack").unwrap_or(LIMIT);
fn transform<'r>(r: &'r Request<'_>, d: Data) -> TransformFuture<'r, Self::Owned, Self::Error> {
Box::pin(async move {
let size_limit = r.limits().get("msgpack").unwrap_or(LIMIT);
let mut buf = Vec::new();
let mut reader = d.open().take(size_limit);
match reader.read_to_end(&mut buf).await {
@ -133,7 +132,7 @@ impl<'a, T: Deserialize<'a>> FromData<'a> for MsgPack<T> {
})
}
fn from_data(_: &Request<'_>, o: Transformed<'a, Self>) -> FromDataFuture<'a, Self, Self::Error> {
fn from_data(_: &'a Request<'_>, o: Transformed<'a, Self>) -> FromDataFuture<'a, Self, Self::Error> {
use self::Error::*;
Box::pin(async move {

View File

@ -112,8 +112,8 @@ pub type Transformed<'a, T> =
Outcome<&'a <T as FromData<'a>>::Borrowed, <T as FromData<'a>>::Error>
>;
pub type TransformFuture<'a, T, E> = BoxFuture<'a, Transform<Outcome<T, E>>>;
pub type FromDataFuture<'a, T, E> = BoxFuture<'a, Outcome<T, E>>;
pub type TransformFuture<'fut, T, E> = BoxFuture<'fut, Transform<Outcome<T, E>>>;
pub type FromDataFuture<'fut, T, E> = BoxFuture<'fut, Outcome<T, E>>;
/// Trait implemented by data guards to derive a value from request body data.
///
@ -212,7 +212,7 @@ pub type FromDataFuture<'a, T, E> = BoxFuture<'a, Outcome<T, E>>;
/// type Owned = String;
/// type Borrowed = str;
///
/// fn transform(_: &Request, data: Data) -> TransformFuture<'a, Self::Owned, Self::Error> {
/// fn transform<'r>(_: &'r Request, data: Data) -> TransformFuture<'r, Self::Owned, Self::Error> {
/// Box::pin(async move {
/// let mut stream = data.open().take(NAME_LIMIT);
/// let mut string = String::with_capacity((NAME_LIMIT / 2) as usize);
@ -226,7 +226,7 @@ pub type FromDataFuture<'a, T, E> = BoxFuture<'a, Outcome<T, E>>;
/// })
/// }
///
/// fn from_data(_: &Request, outcome: Transformed<'a, Self>) -> FromDataFuture<'a, Self, Self::Error> {
/// fn from_data(_: &'a Request, outcome: Transformed<'a, Self>) -> FromDataFuture<'a, Self, Self::Error> {
/// Box::pin(async move {
/// // Retrieve a borrow to the now transformed `String` (an &str). This
/// // is only correct because we know we _always_ return a `Borrowed` from
@ -367,7 +367,7 @@ pub trait FromData<'a>: Sized {
/// If transformation succeeds, an outcome of `Success` is returned.
/// If the data is not appropriate given the type of `Self`, `Forward` is
/// returned. On failure, `Failure` is returned.
fn transform(request: &Request<'_>, data: Data) -> TransformFuture<'a, Self::Owned, Self::Error>;
fn transform<'r>(request: &'r Request<'_>, data: Data) -> TransformFuture<'r, Self::Owned, Self::Error>;
/// Validates, parses, and converts the incoming request body data into an
/// instance of `Self`.
@ -397,7 +397,7 @@ pub trait FromData<'a>: Sized {
/// # unimplemented!()
/// # }
/// ```
fn from_data(request: &Request<'_>, outcome: Transformed<'a, Self>) -> FromDataFuture<'a, Self, Self::Error>;
fn from_data(request: &'a Request<'_>, outcome: Transformed<'a, Self>) -> FromDataFuture<'a, Self, Self::Error>;
}
/// The identity implementation of `FromData`. Always returns `Success`.
@ -407,12 +407,12 @@ impl<'a> FromData<'a> for Data {
type Borrowed = ();
#[inline(always)]
fn transform(_: &Request<'_>, data: Data) -> TransformFuture<'a, Self::Owned, Self::Error> {
fn transform<'r>(_: &'r Request<'_>, data: Data) -> TransformFuture<'r, Self::Owned, Self::Error> {
Box::pin(ready(Transform::Owned(Success(data))))
}
#[inline(always)]
fn from_data(_: &Request<'_>, outcome: Transformed<'a, Self>) -> FromDataFuture<'a, Self, Self::Error> {
fn from_data(_: &'a Request<'_>, outcome: Transformed<'a, Self>) -> FromDataFuture<'a, Self, Self::Error> {
Box::pin(ready(outcome.owned()))
}
}
@ -531,12 +531,12 @@ impl<'a, T: FromDataSimple + 'a> FromData<'a> for T {
type Borrowed = ();
#[inline(always)]
fn transform(_: &Request<'_>, d: Data) -> TransformFuture<'a, Self::Owned, Self::Error> {
fn transform<'r>(_: &'r Request<'_>, d: Data) -> TransformFuture<'r, Self::Owned, Self::Error> {
Box::pin(ready(Transform::Owned(Success(d))))
}
#[inline(always)]
fn from_data(req: &Request<'_>, o: Transformed<'a, Self>) -> FromDataFuture<'a, Self, Self::Error> {
fn from_data(req: &'a Request<'_>, o: Transformed<'a, Self>) -> FromDataFuture<'a, Self, Self::Error> {
match o.owned() {
Success(data) => T::from_data(req, data),
_ => unreachable!(),
@ -550,12 +550,12 @@ impl<'a, T: FromData<'a> + 'a> FromData<'a> for Result<T, T::Error> {
type Borrowed = T::Borrowed;
#[inline(always)]
fn transform(r: &Request<'_>, d: Data) -> TransformFuture<'a, Self::Owned, Self::Error> {
fn transform<'r>(r: &'r Request<'_>, d: Data) -> TransformFuture<'r, Self::Owned, Self::Error> {
T::transform(r, d)
}
#[inline(always)]
fn from_data(r: &Request<'_>, o: Transformed<'a, Self>) -> FromDataFuture<'a, Self, Self::Error> {
fn from_data(r: &'a Request<'_>, o: Transformed<'a, Self>) -> FromDataFuture<'a, Self, Self::Error> {
Box::pin(T::from_data(r, o).map(|x| match x {
Success(val) => Success(Ok(val)),
Forward(data) => Forward(data),
@ -570,12 +570,12 @@ impl<'a, T: FromData<'a> + 'a> FromData<'a> for Option<T> {
type Borrowed = T::Borrowed;
#[inline(always)]
fn transform(r: &Request<'_>, d: Data) -> TransformFuture<'a, Self::Owned, Self::Error> {
fn transform<'r>(r: &'r Request<'_>, d: Data) -> TransformFuture<'r, Self::Owned, Self::Error> {
T::transform(r, d)
}
#[inline(always)]
fn from_data(r: &Request<'_>, o: Transformed<'a, Self>) -> FromDataFuture<'a, Self, Self::Error> {
fn from_data(r: &'a Request<'_>, o: Transformed<'a, Self>) -> FromDataFuture<'a, Self, Self::Error> {
Box::pin(T::from_data(r, o).map(|x| match x {
Success(val) => Success(Some(val)),
Failure(_) | Forward(_) => Success(None),

View File

@ -191,20 +191,20 @@ impl<'f, T: FromForm<'f> + Send + 'f> FromData<'f> for Form<T> {
type Owned = String;
type Borrowed = str;
fn transform(
request: &Request<'_>,
fn transform<'r>(
request: &'r Request<'_>,
data: Data
) -> TransformFuture<'f, Self::Owned, Self::Error> {
use std::cmp::min;
if !request.content_type().map_or(false, |ct| ct.is_form()) {
warn_!("Form data does not have form content type.");
return Box::pin(futures_util::future::ready(Transform::Borrowed(Forward(data))));
}
let limit = request.limits().forms;
let mut stream = data.open().take(limit);
) -> TransformFuture<'r, Self::Owned, Self::Error> {
Box::pin(async move {
use std::cmp::min;
if !request.content_type().map_or(false, |ct| ct.is_form()) {
warn_!("Form data does not have form content type.");
return Transform::Borrowed(Forward(data));
}
let limit = request.limits().forms;
let mut stream = data.open().take(limit);
let mut form_string = String::with_capacity(min(4096, limit) as usize);
if let Err(e) = stream.read_to_string(&mut form_string).await {
return Transform::Borrowed(Failure((Status::InternalServerError, FormDataError::Io(e))));
@ -214,7 +214,7 @@ impl<'f, T: FromForm<'f> + Send + 'f> FromData<'f> for Form<T> {
})
}
fn from_data(_: &Request<'_>, o: Transformed<'f, Self>) -> FromDataFuture<'f, Self, Self::Error> {
fn from_data(_: &'f Request<'_>, o: Transformed<'f, Self>) -> FromDataFuture<'f, Self, Self::Error> {
Box::pin(futures_util::future::ready(o.borrowed().and_then(|data| {
<Form<T>>::from_data(data, true).map(Form)
})))

View File

@ -100,11 +100,11 @@ impl<'f, T: FromForm<'f> + Send + 'f> FromData<'f> for LenientForm<T> {
type Owned = String;
type Borrowed = str;
fn transform(r: &Request<'_>, d: Data) -> TransformFuture<'f, Self::Owned, Self::Error> {
fn transform<'r>(r: &'r Request<'_>, d: Data) -> TransformFuture<'r, Self::Owned, Self::Error> {
<Form<T>>::transform(r, d)
}
fn from_data(_: &Request<'_>, o: Transformed<'f, Self>) -> FromDataFuture<'f, Self, Self::Error> {
fn from_data(_: &'f Request<'_>, o: Transformed<'f, Self>) -> FromDataFuture<'f, Self, Self::Error> {
Box::pin(futures_util::future::ready(o.borrowed().and_then(|form| {
<Form<T>>::from_data(form, false).map(LenientForm)
})))