From 48401f2c8dbe65e5419cdd9f6f15e2885ca0e9df Mon Sep 17 00:00:00 2001 From: David Pedersen Date: Sun, 19 Sep 2021 17:51:25 +0200 Subject: [PATCH] Simplify macros for implementing `Handler` and `FromRequest` (#340) Makes the generated docs nicer and avoids having a recursive macro. --- src/extract/tuple.rs | 32 +++++++++++++++++++++----------- src/handler/mod.rs | 44 ++++++++++++++++++++++++-------------------- 2 files changed, 45 insertions(+), 31 deletions(-) diff --git a/src/extract/tuple.rs b/src/extract/tuple.rs index a921eb86..9d5c2529 100644 --- a/src/extract/tuple.rs +++ b/src/extract/tuple.rs @@ -20,29 +20,39 @@ where } macro_rules! impl_from_request { - () => { - }; + () => {}; - ( $head:ident, $($tail:ident),* $(,)? ) => { + ( $($ty:ident),* $(,)? ) => { #[async_trait] #[allow(non_snake_case)] - impl FromRequest for ($head, $($tail,)*) + impl FromRequest for ($($ty,)*) where - $head: FromRequest + Send, - $( $tail: FromRequest + Send, )* + $( $ty: FromRequest + Send, )* B: Send, { type Rejection = Response; async fn from_request(req: &mut RequestParts) -> Result { - let $head = $head::from_request(req).await.map_err(|err| err.into_response().map(box_body))?; - $( let $tail = $tail::from_request(req).await.map_err(|err| err.into_response().map(box_body))?; )* - Ok(($head, $($tail,)*)) + $( let $ty = $ty::from_request(req).await.map_err(|err| err.into_response().map(box_body))?; )* + Ok(($($ty,)*)) } } - - impl_from_request!($($tail,)*); }; } +impl_from_request!(T1); +impl_from_request!(T1, T2); +impl_from_request!(T1, T2, T3); +impl_from_request!(T1, T2, T3, T4); +impl_from_request!(T1, T2, T3, T4, T5); +impl_from_request!(T1, T2, T3, T4, T5, T6); +impl_from_request!(T1, T2, T3, T4, T5, T6, T7); +impl_from_request!(T1, T2, T3, T4, T5, T6, T7, T8); +impl_from_request!(T1, T2, T3, T4, T5, T6, T7, T8, T9); +impl_from_request!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10); +impl_from_request!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11); +impl_from_request!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12); +impl_from_request!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13); +impl_from_request!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14); +impl_from_request!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15); impl_from_request!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16); diff --git a/src/handler/mod.rs b/src/handler/mod.rs index 6365c1fd..d2ecfaa4 100644 --- a/src/handler/mod.rs +++ b/src/handler/mod.rs @@ -2,7 +2,7 @@ use crate::{ body::{box_body, BoxBody}, - extract::FromRequest, + extract::{FromRequest, RequestParts}, response::IntoResponse, routing::{EmptyRouter, MethodFilter}, service::HandleError, @@ -319,48 +319,52 @@ where } macro_rules! impl_handler { - () => { - }; - - ( $head:ident, $($tail:ident),* $(,)? ) => { + ( $($ty:ident),* $(,)? ) => { #[async_trait] #[allow(non_snake_case)] - impl Handler for F + impl Handler for F where - F: FnOnce($head, $($tail,)*) -> Fut + Clone + Send + Sync + 'static, + F: FnOnce($($ty,)*) -> Fut + Clone + Send + Sync + 'static, Fut: Future + Send, B: Send + 'static, Res: IntoResponse, - $head: FromRequest + Send, - $( $tail: FromRequest + Send,)* + $( $ty: FromRequest + Send,)* { type Sealed = sealed::Hidden; async fn call(self, req: Request) -> Response { - let mut req = crate::extract::RequestParts::new(req); - - let $head = match $head::from_request(&mut req).await { - Ok(value) => value, - Err(rejection) => return rejection.into_response().map(box_body), - }; + let mut req = RequestParts::new(req); $( - let $tail = match $tail::from_request(&mut req).await { + let $ty = match $ty::from_request(&mut req).await { Ok(value) => value, Err(rejection) => return rejection.into_response().map(box_body), }; )* - let res = self($head, $($tail,)*).await; + let res = self($($ty,)*).await; - res.into_response().map(crate::body::box_body) + res.into_response().map(box_body) } } - - impl_handler!($($tail,)*); }; } +impl_handler!(T1); +impl_handler!(T1, T2); +impl_handler!(T1, T2, T3); +impl_handler!(T1, T2, T3, T4); +impl_handler!(T1, T2, T3, T4, T5); +impl_handler!(T1, T2, T3, T4, T5, T6); +impl_handler!(T1, T2, T3, T4, T5, T6, T7); +impl_handler!(T1, T2, T3, T4, T5, T6, T7, T8); +impl_handler!(T1, T2, T3, T4, T5, T6, T7, T8, T9); +impl_handler!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10); +impl_handler!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11); +impl_handler!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12); +impl_handler!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13); +impl_handler!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14); +impl_handler!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15); impl_handler!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16); /// A [`Service`] created from a [`Handler`] by applying a Tower middleware.