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