1use std::marker::PhantomData;
4
5use crate::BoxError;
6use crate::extract::FromRequest;
7use crate::request::Request;
8use crate::response::{IntoResponse, Response};
9use crate::service::Service;
10
11pub fn handler_fn<F, T>(f: F) -> HandlerFn<F, T>
25where
26 HandlerFn<F, T>: Service<Request>,
27{
28 HandlerFn {
29 f,
30 _marker: Default::default(),
31 }
32}
33
34pub struct HandlerFn<F, T> {
36 f: F,
37 _marker: PhantomData<fn(T) -> T>,
38}
39
40impl<F: Clone, T> Clone for HandlerFn<F, T> {
41 fn clone(&self) -> Self {
42 Self {
43 f: self.f.clone(),
44 _marker: Default::default(),
45 }
46 }
47}
48
49impl<F: Copy, T> Copy for HandlerFn<F, T> {}
50
51impl<F, T> std::fmt::Debug for HandlerFn<F, T> {
52 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
53 f.debug_struct("HandlerFn")
54 .field("f", &std::any::type_name::<F>())
55 .finish()
56 }
57}
58
59impl<F, Fut> Service<Request> for HandlerFn<F, ()>
60where
61 F: Fn() -> Fut + Send + Sync,
62 Fut: Future + Send,
63 Fut::Output: IntoResponse,
64{
65 type Response = Response;
66 type Error = BoxError;
67
68 async fn call(&self, _: Request) -> Result<Self::Response, Self::Error> {
69 (self.f)().await.into_response().map_err(Into::into)
70 }
71}
72
73impl<F, Fut> Service<Request> for HandlerFn<F, Request>
74where
75 F: Fn(Request) -> Fut + Send + Sync,
76 Fut: Future + Send,
77 Fut::Output: IntoResponse,
78{
79 type Response = Response;
80 type Error = BoxError;
81
82 async fn call(&self, req: Request) -> Result<Self::Response, Self::Error> {
83 (self.f)(req).await.into_response().map_err(Into::into)
84 }
85}
86
87macro_rules! handler_tuples {
88 ($($ty:ident),*) => {
89 #[allow(non_snake_case)]
90 impl<F, Fut, $($ty,)*> Service<Request> for HandlerFn<F, ($($ty,)*)>
91 where
92 F: Fn($($ty,)*) -> Fut + Send + Sync,
93 Fut: Future + Send,
94 Fut::Output: IntoResponse,
95 $($ty: FromRequest + Send,)*
96 $(<$ty as FromRequest>::Error: Into<BoxError>,)*
97 {
98 type Response = Response;
99 type Error = BoxError;
100
101 async fn call(&self, mut req: Request) -> Result<Self::Response, Self::Error> {
102 $(
103 let $ty = $ty::from_request(&mut req).await.map_err(Into::into)?;
104 )*
105 (self.f)($($ty,)*).await.into_response().map_err(Into::into)
106 }
107 }
108
109 #[allow(non_snake_case)]
110 impl<F, Fut, $($ty,)*> Service<Request> for HandlerFn<F, ($($ty,)* Request)>
111 where
112 F: Fn($($ty,)* Request) -> Fut + Send + Sync,
113 Fut: Future + Send,
114 Fut::Output: IntoResponse,
115 $($ty: FromRequest + Send,)*
116 $(<$ty as FromRequest>::Error: Into<BoxError>,)*
117 {
118 type Response = Response;
119 type Error = BoxError;
120
121 async fn call(&self, mut req: Request) -> Result<Self::Response, Self::Error> {
122 $(
123 let $ty = $ty::from_request(&mut req).await.map_err(Into::into)?;
124 )*
125 (self.f)($($ty,)* req).await.into_response().map_err(Into::into)
126 }
127 }
128 };
129}
130
131handler_tuples!(T1);
132handler_tuples!(T1, T2);
133handler_tuples!(T1, T2, T3);
134handler_tuples!(T1, T2, T3, T4);
135handler_tuples!(T1, T2, T3, T4, T5);
136handler_tuples!(T1, T2, T3, T4, T5, T6);
137handler_tuples!(T1, T2, T3, T4, T5, T6, T7);
138handler_tuples!(T1, T2, T3, T4, T5, T6, T7, T8);
139handler_tuples!(T1, T2, T3, T4, T5, T6, T7, T8, T9);
140handler_tuples!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
141handler_tuples!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);
142handler_tuples!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12);
143handler_tuples!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13);
144handler_tuples!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14);
145handler_tuples!(
146 T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15
147);
148handler_tuples!(
149 T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16
150);