nuclear/
functional.rs

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}