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