1use std::future::Future;
2use std::pin::Pin;
3use crate::{Request, Response};
4use crate::extractors::{FromRequestParts, IntoResponse};
5
6pub trait Handler<T>: Clone + Send + Sync + 'static {
8 type Future: Future<Output = Response> + Send + 'static;
10
11 fn call(&self, req: Request) -> Self::Future;
13}
14
15pub type HandlerFn = std::sync::Arc<
17 dyn Fn(Request) -> Pin<Box<dyn Future<Output = Response> + Send + 'static>>
18 + Send
19 + Sync
20 + 'static,
21>;
22
23impl<F, Fut> Handler<()> for F
25where
26 F: Fn(Request) -> Fut + Clone + Send + Sync + 'static,
27 Fut: Future<Output = Response> + Send + 'static,
28{
29 type Future = Fut;
30
31 fn call(&self, req: Request) -> Self::Future {
32 self(req)
33 }
34}
35
36impl<F, Fut, Res> Handler<((),)> for F
40where
41 F: Fn() -> Fut + Clone + Send + Sync + 'static,
42 Fut: Future<Output = Res> + Send + 'static,
43 Res: IntoResponse,
44{
45 type Future = Pin<Box<dyn Future<Output = Response> + Send + 'static>>;
46
47 fn call(&self, _req: Request) -> Self::Future {
48 let fut = self();
49 Box::pin(async move {
50 let res = fut.await;
51 res.into_response()
52 })
53 }
54}
55
56impl<F, Fut, Res, E1> Handler<(E1,)> for F
58where
59 F: Fn(E1) -> Fut + Clone + Send + Sync + 'static,
60 Fut: Future<Output = Res> + Send + 'static,
61 Res: IntoResponse,
62 E1: FromRequestParts + Send + 'static,
63{
64 type Future = Pin<Box<dyn Future<Output = Response> + Send + 'static>>;
65
66 fn call(&self, mut req: Request) -> Self::Future {
67 let handler = self.clone();
68 Box::pin(async move {
69 match E1::from_request_parts(&mut req).await {
70 Ok(e1) => {
71 let res = handler(e1).await;
72 res.into_response()
73 }
74 Err(err) => err.into_response(),
75 }
76 })
77 }
78}
79
80impl<F, Fut, Res, E1, E2> Handler<(E1, E2)> for F
82where
83 F: Fn(E1, E2) -> Fut + Clone + Send + Sync + 'static,
84 Fut: Future<Output = Res> + Send + 'static,
85 Res: IntoResponse,
86 E1: FromRequestParts + Send + 'static,
87 E2: FromRequestParts + Send + 'static,
88{
89 type Future = Pin<Box<dyn Future<Output = Response> + Send + 'static>>;
90
91 fn call(&self, mut req: Request) -> Self::Future {
92 let handler = self.clone();
93 Box::pin(async move {
94 let e1 = match E1::from_request_parts(&mut req).await {
95 Ok(e1) => e1,
96 Err(err) => return err.into_response(),
97 };
98
99 let e2 = match E2::from_request_parts(&mut req).await {
100 Ok(e2) => e2,
101 Err(err) => return err.into_response(),
102 };
103
104 let res = handler(e1, e2).await;
105 res.into_response()
106 })
107 }
108}
109
110impl<F, Fut, Res, E1, E2, E3> Handler<(E1, E2, E3)> for F
112where
113 F: Fn(E1, E2, E3) -> Fut + Clone + Send + Sync + 'static,
114 Fut: Future<Output = Res> + Send + 'static,
115 Res: IntoResponse,
116 E1: FromRequestParts + Send + 'static,
117 E2: FromRequestParts + Send + 'static,
118 E3: FromRequestParts + Send + 'static,
119{
120 type Future = Pin<Box<dyn Future<Output = Response> + Send + 'static>>;
121
122 fn call(&self, mut req: Request) -> Self::Future {
123 let handler = self.clone();
124 Box::pin(async move {
125 let e1 = match E1::from_request_parts(&mut req).await {
126 Ok(e1) => e1,
127 Err(err) => return err.into_response(),
128 };
129
130 let e2 = match E2::from_request_parts(&mut req).await {
131 Ok(e2) => e2,
132 Err(err) => return err.into_response(),
133 };
134
135 let e3 = match E3::from_request_parts(&mut req).await {
136 Ok(e3) => e3,
137 Err(err) => return err.into_response(),
138 };
139
140 let res = handler(e1, e2, e3).await;
141 res.into_response()
142 })
143 }
144}
145
146impl<F, Fut, Res, E1, E2, E3, E4> Handler<(E1, E2, E3, E4)> for F
148where
149 F: Fn(E1, E2, E3, E4) -> Fut + Clone + Send + Sync + 'static,
150 Fut: Future<Output = Res> + Send + 'static,
151 Res: IntoResponse,
152 E1: FromRequestParts + Send + 'static,
153 E2: FromRequestParts + Send + 'static,
154 E3: FromRequestParts + Send + 'static,
155 E4: FromRequestParts + Send + 'static,
156{
157 type Future = Pin<Box<dyn Future<Output = Response> + Send + 'static>>;
158
159 fn call(&self, mut req: Request) -> Self::Future {
160 let handler = self.clone();
161 Box::pin(async move {
162 let e1 = match E1::from_request_parts(&mut req).await {
163 Ok(e1) => e1,
164 Err(err) => return err.into_response(),
165 };
166
167 let e2 = match E2::from_request_parts(&mut req).await {
168 Ok(e2) => e2,
169 Err(err) => return err.into_response(),
170 };
171
172 let e3 = match E3::from_request_parts(&mut req).await {
173 Ok(e3) => e3,
174 Err(err) => return err.into_response(),
175 };
176
177 let e4 = match E4::from_request_parts(&mut req).await {
178 Ok(e4) => e4,
179 Err(err) => return err.into_response(),
180 };
181
182 let res = handler(e1, e2, e3, e4).await;
183 res.into_response()
184 })
185 }
186}
187
188pub fn into_handler_fn<H, T>(handler: H) -> HandlerFn
190where
191 H: Handler<T>,
192{
193 std::sync::Arc::new(move |req| Box::pin(handler.call(req)))
194}
195
196impl<F, Fut, Res> Handler<(Request,)> for F
200where
201 F: Fn(Request) -> Fut + Clone + Send + Sync + 'static,
202 Fut: Future<Output = Res> + Send + 'static,
203 Res: IntoResponse,
204{
205 type Future = Pin<Box<dyn Future<Output = Response> + Send + 'static>>;
206
207 fn call(&self, req: Request) -> Self::Future {
208 let handler = self.clone();
209 Box::pin(async move {
210 let res = handler(req).await;
211 res.into_response()
212 })
213 }
214}
215
216#[macro_export]
218macro_rules! handler {
219 ($body:expr) => {
220 |_req: $crate::Request| async move { $body }
221 };
222 ($req:ident => $body:expr) => {
223 |$req: $crate::Request| async move { $body }
224 };
225}
226
227#[cfg(test)]
228mod tests {
229 use super::*;
230 use crate::Response;
231
232 #[tokio::test]
233 async fn test_async_handler() {
234 let handler = |_req: Request| async {
235 Response::ok().body("Hello from async handler")
236 };
237
238 let req = Request::from_hyper(
239 http::Request::builder()
240 .method("GET")
241 .uri("/")
242 .body(())
243 .unwrap()
244 .into_parts()
245 .0,
246 Vec::new(),
247 )
248 .await
249 .unwrap();
250
251 let response = handler.call(req).await;
252 assert_eq!(response.body_data(), b"Hello from async handler");
253 }
254
255 #[tokio::test]
256 async fn test_sync_handler() {
257 let handler = |_req: Request| Response::ok().body("Hello from sync handler");
258
259 let req = Request::from_hyper(
260 http::Request::builder()
261 .method("GET")
262 .uri("/")
263 .body(())
264 .unwrap()
265 .into_parts()
266 .0,
267 Vec::new(),
268 )
269 .await
270 .unwrap();
271
272 let response = handler.call(req).await;
273 assert_eq!(response.body_data(), b"Hello from sync handler");
274 }
275
276 #[test]
277 fn test_handler_macro() {
278 let _handler1 = handler!(Response::ok().body("Simple response"));
279 let _handler2 = handler!(req => {
280 Response::ok().body(format!("Path: {}", req.path()))
281 });
282 }
283}