1use axum::extract::{FromRequest, FromRequestParts, Request};
2use std::{future::Future, pin::Pin};
3
4use crate::{context::Context, CoaxialResponse};
5
6pub trait CoaxialHandler<T, S>: Clone + Send + Sized + 'static {
7 type Future: Future<Output = CoaxialResponse<S>> + Send + 'static;
8 fn call(self, req: Request, state: S) -> Self::Future;
9}
10
11impl<F, Fut, S> CoaxialHandler<((),), S> for F
13where
14 F: FnOnce(Context<S>) -> Fut + Clone + Send + 'static,
15 Fut: Future<Output = CoaxialResponse<S>> + Send,
16 S: Send + Sync + 'static,
17{
18 type Future = Pin<Box<dyn Future<Output = CoaxialResponse<S>> + Send>>;
19
20 fn call(self, _req: Request, _state: S) -> Self::Future {
21 Box::pin(async move { self(Context::default()).await })
22 }
23}
24
25macro_rules! impl_handler {
26 (
27 [$($ty:ident),*], $last:ident
28 ) => {
29 #[allow(non_snake_case, unused_mut)]
30 impl<F, Fut, S, M, $($ty,)* $last> CoaxialHandler<((M, $($ty,)* $last,),), S> for F
31 where
32 F: FnOnce(Context<S>, $($ty,)* $last,) -> Fut + Clone + Send + 'static,
33 Fut: Future<Output = CoaxialResponse<S>> + Send,
34 S: Send + Sync + 'static,
35 $( $ty: FromRequestParts<S> + Send, )*
36 $last: FromRequest<S, M> + Send,
37 {
38 type Future = Pin<Box<dyn Future<Output = CoaxialResponse<S>> + Send>>;
39
40 fn call(self, req: Request, state: S) -> Self::Future {
41 Box::pin(async move {
42 let (mut parts, body) = req.into_parts();
43 let state = &state;
44
45 $(
46 let $ty = match $ty::from_request_parts(&mut parts, state).await {
47 Ok(value) => value,
48 Err(_rejection) => todo!("rejections aren't handled yet"),
49 };
50 )*
51
52 let req = Request::from_parts(parts, body);
53
54 let $last = match $last::from_request(req, state).await {
55 Ok(value) => value,
56 Err(_rejection) => todo!("rejections aren't handled yet"),
57 };
58
59 self(Context::default(), $($ty,)* $last,).await
60 })
61 }
62 }
63 };
64}
65
66#[rustfmt::skip]
67macro_rules! all_the_tuples {
68 ($name:ident) => {
69 $name!([], T1);
70 $name!([T1], T2);
71 $name!([T1, T2], T3);
72 $name!([T1, T2, T3], T4);
73 $name!([T1, T2, T3, T4], T5);
74 $name!([T1, T2, T3, T4, T5], T6);
75 $name!([T1, T2, T3, T4, T5, T6], T7);
76 $name!([T1, T2, T3, T4, T5, T6, T7], T8);
77 $name!([T1, T2, T3, T4, T5, T6, T7, T8], T9);
78 $name!([T1, T2, T3, T4, T5, T6, T7, T8, T9], T10);
79 $name!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10], T11);
80 $name!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11], T12);
81 $name!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12], T13);
82 $name!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13], T14);
83 $name!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14], T15);
84 $name!([T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15], T16);
85 };
86}
87
88all_the_tuples!(impl_handler);