1use crate::handler::Handler;
2use crate::internal_prelude::*;
3use crate::state;
4
5use std::any::type_name;
6use std::convert::TryInto;
7use std::marker::PhantomData;
8use std::sync::Arc;
9
10mod sealed {
11 use std::future::Future;
12
13 pub trait AsyncFn<'a, A>: Send + Sync + 'a {
14 type Future: Future<Output = Self::Output> + Send + 'a;
15 type Output: 'a;
16
17 fn call<'t: 'a>(&'t self, args: A) -> Self::Future;
18 }
19
20 macro_rules! impl_async_fn {
21 (($($ty:tt,)+),($($id:tt,)+)) => {
22 impl<'a, $($ty,)+ F, U, O> AsyncFn<'a, ($($ty,)+)> for F
23 where
24 $($ty:'a,)+
25 F: Fn($($ty,)+) -> U + Send + Sync + 'a,
26 U: Future<Output = O> + Send + 'a,
27 O: 'a,
28 {
29 type Future = U;
30
31 type Output = O;
32
33 fn call<'t: 'a>(&'t self, ($($id,)+): ($($ty,)+)) -> Self::Future {
34 (self)($($id,)+)
35 }
36 }
37 };
38 }
39
40 impl_async_fn!((A0,), (a0,));
41 impl_async_fn!((A0, A1,), (a0, a1,));
42 impl_async_fn!((A0, A1, A2,), (a0, a1, a2,));
43}
44
45use self::sealed::AsyncFn;
46
47pub fn handler<F>(f: F) -> HandlerFn<F> {
48 HandlerFn { f }
49}
50
51pub struct HandlerFn<F> {
52 f: F,
53}
54
55impl<F, R> Handler for HandlerFn<F>
56where
57 F: for<'a> AsyncFn<'a, (Request,), Output = R>,
58 R: TryInto<Response>,
59 R::Error: Into<Error>,
60{
61 fn handle<'t, 'a>(&'t self, req: Request) -> BoxFuture<'a, Result<Response>>
62 where
63 't: 'a,
64 Self: 'a,
65 {
66 Box::pin(async move {
67 AsyncFn::call(&self.f, (req,))
68 .await
69 .try_into()
70 .map_err(Into::into)
71 })
72 }
73}
74
75impl<F> Clone for HandlerFn<F>
76where
77 F: Clone,
78{
79 fn clone(&self) -> Self {
80 Self { f: self.f.clone() }
81 }
82}
83
84pub fn ref_handler<S, F>(f: F) -> RefHandlerFn<S, F> {
85 RefHandlerFn {
86 f,
87 _marker: PhantomData,
88 }
89}
90
91pub struct RefHandlerFn<S, F> {
92 f: F,
93 _marker: PhantomData<fn(&S)>,
94}
95
96impl<S, F, R> Handler for RefHandlerFn<S, F>
97where
98 S: Send + Sync + 'static,
99 F: for<'a> AsyncFn<'a, (&'a S, Request), Output = R>,
100 R: TryInto<Response>,
101 R::Error: Into<Error>,
102{
103 #[track_caller]
104 fn handle<'t, 'a>(&'t self, req: Request) -> BoxFuture<'a, Result<Response>>
105 where
106 't: 'a,
107 Self: 'a,
108 {
109 let state = match state::inject::<S>() {
110 Some(s) => s,
111 None => panic!(
112 "failed to inject state <{}> for handler <{}>",
113 type_name::<S>(),
114 type_name::<F>(),
115 ),
116 };
117 Box::pin(async move {
118 AsyncFn::call(&self.f, (&*state, req))
119 .await
120 .try_into()
121 .map_err(Into::into)
122 })
123 }
124}
125
126impl<S, F> Clone for RefHandlerFn<S, F>
127where
128 F: Clone,
129{
130 fn clone(&self) -> Self {
131 Self {
132 f: self.f.clone(),
133 _marker: PhantomData,
134 }
135 }
136}
137
138pub fn arc_handler<S, F>(f: F) -> ArcHandlerFn<S, F> {
139 ArcHandlerFn {
140 f,
141 _marker: PhantomData,
142 }
143}
144
145pub struct ArcHandlerFn<S, F> {
146 f: F,
147 _marker: PhantomData<fn(Arc<S>)>,
148}
149
150impl<S, F, R> Handler for ArcHandlerFn<S, F>
151where
152 S: Send + Sync + 'static,
153 F: for<'a> AsyncFn<'a, (Arc<S>, Request), Output = R>,
154 R: TryInto<Response>,
155 R::Error: Into<Error>,
156{
157 #[track_caller]
158 fn handle<'t, 'a>(&'t self, req: Request) -> BoxFuture<'a, Result<Response>>
159 where
160 't: 'a,
161 Self: 'a,
162 {
163 let state = match state::inject::<S>() {
164 Some(s) => s,
165 None => panic!(
166 "failed to inject state <{}> for handler <{}>",
167 type_name::<S>(),
168 type_name::<F>(),
169 ),
170 };
171 Box::pin(async move {
172 AsyncFn::call(&self.f, (state, req))
173 .await
174 .try_into()
175 .map_err(Into::into)
176 })
177 }
178}
179
180impl<S, F> Clone for ArcHandlerFn<S, F>
181where
182 F: Clone,
183{
184 fn clone(&self) -> Self {
185 Self {
186 f: self.f.clone(),
187 _marker: PhantomData,
188 }
189 }
190}
191
192pub fn middleware<F>(f: F) -> MiddlewareFn<F> {
193 MiddlewareFn { f }
194}
195
196pub struct MiddlewareFn<F> {
197 f: F,
198}
199
200impl<F> Middleware for MiddlewareFn<F>
201where
202 F: for<'a> AsyncFn<'a, (Request, &'a dyn Handler), Output = Result<Response>>,
203{
204 fn handle<'t, 'n, 'a>(
205 &'t self,
206 req: Request,
207 next: &'a dyn Handler,
208 ) -> BoxFuture<'a, Result<Response>>
209 where
210 't: 'a,
211 'n: 'a,
212 Self: 'a,
213 {
214 Box::pin(AsyncFn::call(&self.f, (req, next)))
215 }
216}
217
218impl<F> Clone for MiddlewareFn<F>
219where
220 F: Clone,
221{
222 fn clone(&self) -> Self {
223 Self { f: self.f.clone() }
224 }
225}
226
227pub fn ref_middleware<S, F>(f: F) -> RefMiddlewareFn<S, F>
228where
229 S: Send + Sync + 'static,
230 F: for<'a> AsyncFn<'a, (&'a S, Request, &'a dyn Handler)>,
231{
232 RefMiddlewareFn {
233 f,
234 _marker: PhantomData,
235 }
236}
237
238pub struct RefMiddlewareFn<S, F> {
239 f: F,
240 _marker: PhantomData<fn(&S)>,
241}
242
243impl<S, F> Middleware for RefMiddlewareFn<S, F>
244where
245 S: Send + Sync + 'static,
246 F: for<'a> AsyncFn<'a, (&'a S, Request, &'a dyn Handler), Output = Result<Response>>,
247{
248 fn handle<'t, 'n, 'a>(
249 &'t self,
250 req: Request,
251 next: &'a dyn Handler,
252 ) -> BoxFuture<'a, Result<Response>>
253 where
254 't: 'a,
255 'n: 'a,
256 Self: 'a,
257 {
258 let state = match state::inject::<S>() {
259 Some(s) => s,
260 None => panic!(
261 "failed to inject state <{}> for middleware <{}>",
262 type_name::<S>(),
263 type_name::<F>(),
264 ),
265 };
266 Box::pin(async move { AsyncFn::call(&self.f, (&*state, req, next)).await })
267 }
268}
269
270impl<S, F> Clone for RefMiddlewareFn<S, F>
271where
272 F: Clone,
273{
274 fn clone(&self) -> Self {
275 Self {
276 f: self.f.clone(),
277 _marker: PhantomData,
278 }
279 }
280}
281
282pub fn arc_middleware<S, F>(f: F) -> ArcMiddlewareFn<S, F>
283where
284 S: Send + Sync + 'static,
285 F: for<'a> AsyncFn<'a, (Arc<S>, Request, &'a dyn Handler)>,
286{
287 ArcMiddlewareFn {
288 f,
289 _marker: PhantomData,
290 }
291}
292
293pub struct ArcMiddlewareFn<S, F> {
294 f: F,
295 _marker: PhantomData<fn(&S)>,
296}
297
298impl<S, F> Middleware for ArcMiddlewareFn<S, F>
299where
300 S: Send + Sync + 'static,
301 F: for<'a> AsyncFn<'a, (Arc<S>, Request, &'a dyn Handler), Output = Result<Response>>,
302{
303 fn handle<'t, 'n, 'a>(
304 &'t self,
305 req: Request,
306 next: &'a dyn Handler,
307 ) -> BoxFuture<'a, Result<Response>>
308 where
309 't: 'a,
310 'n: 'a,
311 Self: 'a,
312 {
313 let state = match state::inject::<S>() {
314 Some(s) => s,
315 None => panic!(
316 "failed to inject state <{}> for middleware <{}>",
317 type_name::<S>(),
318 type_name::<F>(),
319 ),
320 };
321 Box::pin(async move { AsyncFn::call(&self.f, (state, req, next)).await })
322 }
323}
324
325impl<S, F> Clone for ArcMiddlewareFn<S, F>
326where
327 F: Clone,
328{
329 fn clone(&self) -> Self {
330 Self {
331 f: self.f.clone(),
332 _marker: PhantomData,
333 }
334 }
335}