Skip to content

Commit f3db866

Browse files
jebrosenSergioBenitez
authored andcommitted
Add 'FromRequestAsync' and use it in route codegen.
'FromRequestAsync' is automatically implemented for all types that implement 'FromRequest'.
1 parent 38cd92c commit f3db866

File tree

3 files changed

+28
-2
lines changed

3 files changed

+28
-2
lines changed

core/codegen/src/attribute/route.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ fn request_guard_expr(ident: &syn::Ident, ty: &syn::Type) -> TokenStream2 {
313313
let span = ident.span().unstable().join(ty.span()).unwrap().into();
314314
quote_spanned! { span =>
315315
#[allow(non_snake_case, unreachable_patterns, unreachable_code)]
316-
let #ident: #ty = match <#ty as #request::FromRequest>::from_request(#req) {
316+
let #ident: #ty = match <#ty as #request::FromRequestAsync>::from_request(#req).await {
317317
#Outcome::Success(__v) => __v,
318318
#Outcome::Forward(_) => return #Outcome::Forward(#data),
319319
#Outcome::Failure((__c, _)) => return #Outcome::Failure(__c),

core/lib/src/request/from_request.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use std::fmt::Debug;
22
use std::net::SocketAddr;
33

4+
use futures_core::future::BoxFuture;
5+
46
use crate::router::Route;
57
use crate::request::Request;
68
use crate::outcome::{self, IntoOutcome};
@@ -32,6 +34,22 @@ impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> {
3234
}
3335
}
3436

37+
/// Type alias for the future returned by [`FromRequestAsync::from_request`].
38+
pub type FromRequestFuture<'fut, T, E> = BoxFuture<'fut, Outcome<T, E>>;
39+
40+
pub trait FromRequestAsync<'a, 'r>: Sized {
41+
/// The associated error to be returned if derivation fails.
42+
type Error: Debug;
43+
44+
/// Derives an instance of `Self` from the incoming request metadata.
45+
///
46+
/// If the derivation is successful, an outcome of `Success` is returned. If
47+
/// the derivation fails in an unrecoverable fashion, `Failure` is returned.
48+
/// `Forward` is returned to indicate that the request should be forwarded
49+
/// to other matching routes, if any.
50+
fn from_request<'fut>(request: &'a Request<'r>) -> FromRequestFuture<'fut, Self, Self::Error> where 'a: 'fut;
51+
}
52+
3553
/// Trait implemented by request guards to derive a value from incoming
3654
/// requests.
3755
///
@@ -356,6 +374,14 @@ pub trait FromRequest<'a, 'r>: Sized {
356374
fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error>;
357375
}
358376

377+
impl<'a, 'r, T: FromRequest<'a, 'r>> FromRequestAsync<'a, 'r> for T {
378+
type Error = T::Error;
379+
380+
fn from_request<'fut>(request: &'a Request<'r>) -> BoxFuture<'fut, Outcome<Self, Self::Error>> where 'a: 'fut {
381+
Box::pin(async move { T::from_request(request) })
382+
}
383+
}
384+
359385
impl FromRequest<'_, '_> for Method {
360386
type Error = std::convert::Infallible;
361387

core/lib/src/request/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ mod tests;
1313
#[doc(hidden)] pub use rocket_codegen::{FromForm, FromFormValue};
1414

1515
pub use self::request::Request;
16-
pub use self::from_request::{FromRequest, Outcome};
16+
pub use self::from_request::{FromRequest, FromRequestAsync, FromRequestFuture, Outcome};
1717
pub use self::param::{FromParam, FromSegments};
1818
pub use self::form::{FromForm, FromFormValue};
1919
pub use self::form::{Form, LenientForm, FormItems, FormItem};

0 commit comments

Comments
 (0)