1use std::convert::Infallible;
4
5use http::{Extensions, HeaderMap, Method, Uri, Version};
6
7use crate::BoxError;
8use crate::body::{Body, Bytes};
9use crate::request::{Request, RequestParts};
10
11pub trait FromRequest: Sized {
41 type Error;
43
44 fn from_request(req: &mut Request) -> impl Future<Output = Result<Self, Self::Error>> + Send;
46}
47
48pub trait OptionalFromRequest: Sized {
81 type Error;
83
84 fn from_request(
86 req: &mut Request,
87 ) -> impl Future<Output = Result<Option<Self>, Self::Error>> + Send;
88}
89
90impl<T> FromRequest for Option<T>
91where
92 T: OptionalFromRequest,
93{
94 type Error = T::Error;
95
96 async fn from_request(req: &mut Request) -> Result<Self, Self::Error> {
97 T::from_request(req).await
98 }
99}
100
101impl<T> FromRequest for Result<T, T::Error>
102where
103 T: FromRequest,
104{
105 type Error = Infallible;
106
107 async fn from_request(req: &mut Request) -> Result<Self, Self::Error> {
108 Ok(T::from_request(req).await)
109 }
110}
111
112macro_rules! from_request_tuples {
113 ($($ty:ident),*) => {
114 #[allow(non_snake_case)]
115 impl<$($ty,)*> FromRequest for ($($ty,)*)
116 where
117 $($ty: FromRequest + Send,)*
118 $(<$ty as FromRequest>::Error: Into<BoxError>,)*
119 {
120 type Error = BoxError;
121
122 async fn from_request(req: &mut Request) -> Result<Self, Self::Error> {
123 $(
124 let $ty = $ty::from_request(req).await.map_err(Into::into)?;
125 )*
126 Ok(($($ty,)*))
127 }
128 }
129 };
130}
131
132from_request_tuples!(T1);
133from_request_tuples!(T1, T2);
134from_request_tuples!(T1, T2, T3);
135from_request_tuples!(T1, T2, T3, T4);
136from_request_tuples!(T1, T2, T3, T4, T5);
137from_request_tuples!(T1, T2, T3, T4, T5, T6);
138from_request_tuples!(T1, T2, T3, T4, T5, T6, T7);
139from_request_tuples!(T1, T2, T3, T4, T5, T6, T7, T8);
140from_request_tuples!(T1, T2, T3, T4, T5, T6, T7, T8, T9);
141from_request_tuples!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
142from_request_tuples!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);
143from_request_tuples!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12);
144from_request_tuples!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13);
145from_request_tuples!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14);
146from_request_tuples!(
147 T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15
148);
149from_request_tuples!(
150 T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16
151);
152
153impl FromRequest for Body {
154 type Error = Infallible;
155
156 async fn from_request(req: &mut Request) -> Result<Self, Self::Error> {
157 Ok(std::mem::take(req.body_mut()))
158 }
159}
160
161impl FromRequest for Bytes {
162 type Error = BoxError;
163
164 async fn from_request(req: &mut Request) -> Result<Self, Self::Error> {
165 std::mem::take(req.body_mut()).to_bytes().await
166 }
167}
168
169impl FromRequest for String {
170 type Error = BoxError;
171
172 async fn from_request(req: &mut Request) -> Result<Self, Self::Error> {
173 let bytes = Bytes::from_request(req).await?;
174 Ok(std::str::from_utf8(&bytes)?.to_owned())
175 }
176}
177
178impl FromRequest for Method {
179 type Error = Infallible;
180
181 async fn from_request(req: &mut Request) -> Result<Self, Self::Error> {
182 Ok(req.method().clone())
183 }
184}
185
186impl FromRequest for Uri {
187 type Error = Infallible;
188
189 async fn from_request(req: &mut Request) -> Result<Self, Self::Error> {
190 Ok(req.uri().clone())
191 }
192}
193
194impl FromRequest for Version {
195 type Error = Infallible;
196
197 async fn from_request(req: &mut Request) -> Result<Self, Self::Error> {
198 Ok(req.version())
199 }
200}
201
202impl FromRequest for HeaderMap {
203 type Error = Infallible;
204
205 async fn from_request(req: &mut Request) -> Result<Self, Self::Error> {
206 Ok(req.headers().clone())
207 }
208}
209
210impl FromRequest for Extensions {
211 type Error = Infallible;
212
213 async fn from_request(req: &mut Request) -> Result<Self, Self::Error> {
214 Ok(req.extensions().clone())
215 }
216}
217
218impl FromRequest for RequestParts {
219 type Error = Infallible;
220
221 async fn from_request(req: &mut Request) -> Result<Self, Self::Error> {
222 Ok(req.parts().clone())
223 }
224}
225
226pub type ExtractResult<T> = std::result::Result<T, <T as FromRequest>::Error>;