1 use super::{FromRequest, FromRequestParts};
2 use crate::response::{IntoResponse, Response};
3 use async_trait::async_trait;
4 use http::request::{Parts, Request};
5 use std::convert::Infallible;
6 
7 #[async_trait]
8 impl<S> FromRequestParts<S> for ()
9 where
10     S: Send + Sync,
11 {
12     type Rejection = Infallible;
13 
from_request_parts(_: &mut Parts, _: &S) -> Result<(), Self::Rejection>14     async fn from_request_parts(_: &mut Parts, _: &S) -> Result<(), Self::Rejection> {
15         Ok(())
16     }
17 }
18 
19 macro_rules! impl_from_request {
20     (
21         [$($ty:ident),*], $last:ident
22     ) => {
23         #[async_trait]
24         #[allow(non_snake_case, unused_mut, unused_variables)]
25         impl<S, $($ty,)* $last> FromRequestParts<S> for ($($ty,)* $last,)
26         where
27             $( $ty: FromRequestParts<S> + Send, )*
28             $last: FromRequestParts<S> + Send,
29             S: Send + Sync,
30         {
31             type Rejection = Response;
32 
33             async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {
34                 $(
35                     let $ty = $ty::from_request_parts(parts, state)
36                         .await
37                         .map_err(|err| err.into_response())?;
38                 )*
39                 let $last = $last::from_request_parts(parts, state)
40                     .await
41                     .map_err(|err| err.into_response())?;
42 
43                 Ok(($($ty,)* $last,))
44             }
45         }
46 
47         // This impl must not be generic over M, otherwise it would conflict with the blanket
48         // implementation of `FromRequest<S, B, Mut>` for `T: FromRequestParts<S>`.
49         #[async_trait]
50         #[allow(non_snake_case, unused_mut, unused_variables)]
51         impl<S, B, $($ty,)* $last> FromRequest<S, B> for ($($ty,)* $last,)
52         where
53             $( $ty: FromRequestParts<S> + Send, )*
54             $last: FromRequest<S, B> + Send,
55             B: Send + 'static,
56             S: Send + Sync,
57         {
58             type Rejection = Response;
59 
60             async fn from_request(req: Request<B>, state: &S) -> Result<Self, Self::Rejection> {
61                 let (mut parts, body) = req.into_parts();
62 
63                 $(
64                     let $ty = $ty::from_request_parts(&mut parts, state).await.map_err(|err| err.into_response())?;
65                 )*
66 
67                 let req = Request::from_parts(parts, body);
68 
69                 let $last = $last::from_request(req, state).await.map_err(|err| err.into_response())?;
70 
71                 Ok(($($ty,)* $last,))
72             }
73         }
74     };
75 }
76 
77 all_the_tuples!(impl_from_request);
78 
79 #[cfg(test)]
80 mod tests {
81     use bytes::Bytes;
82     use http::Method;
83 
84     use crate::extract::{FromRequest, FromRequestParts};
85 
assert_from_request<M, T>() where T: FromRequest<(), http_body::Full<Bytes>, M>,86     fn assert_from_request<M, T>()
87     where
88         T: FromRequest<(), http_body::Full<Bytes>, M>,
89     {
90     }
91 
assert_from_request_parts<T: FromRequestParts<()>>()92     fn assert_from_request_parts<T: FromRequestParts<()>>() {}
93 
94     #[test]
unit()95     fn unit() {
96         assert_from_request_parts::<()>();
97         assert_from_request::<_, ()>();
98     }
99 
100     #[test]
tuple_of_one()101     fn tuple_of_one() {
102         assert_from_request_parts::<(Method,)>();
103         assert_from_request::<_, (Method,)>();
104         assert_from_request::<_, (Bytes,)>();
105     }
106 
107     #[test]
tuple_of_two()108     fn tuple_of_two() {
109         assert_from_request_parts::<((), ())>();
110         assert_from_request::<_, ((), ())>();
111         assert_from_request::<_, (Method, Bytes)>();
112     }
113 
114     #[test]
nested_tuple()115     fn nested_tuple() {
116         assert_from_request_parts::<(((Method,),),)>();
117         assert_from_request::<_, ((((Bytes,),),),)>();
118     }
119 }
120