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