teo_runtime/middleware/
middleware_imp.rs

1use std::future::Future;
2use futures_util::future::BoxFuture;
3use crate::middleware::Middleware;
4use crate::middleware::next::{Next, NextImp};
5use crate::request::Request;
6use crate::request::extract::ExtractFromRequest;
7use crate::response::Response;
8
9pub trait MiddlewareImp: Send + Sync {
10    fn call(&self, request: Request, next: Next) -> BoxFuture<'static, teo_result::Result<Response>>;
11}
12
13impl<F, Fut> MiddlewareImp for F where
14    F: Fn(Request, Next) -> Fut + Sync + Send,
15    Fut: Future<Output = teo_result::Result<Response>> + Send + 'static {
16    fn call(&self, request: Request, next: Next) -> BoxFuture<'static, teo_result::Result<Response>> {
17        Box::pin(self(request, next))
18    }
19}
20
21pub(crate) fn empty_middleware() -> Middleware {
22    Middleware::new(|request: Request, next: Next| async move {
23        next.call(request).await
24    })
25}
26
27pub(crate) fn combine_middleware(middlewares: Vec<Middleware>) -> Middleware {
28    match middlewares.len() {
29        0 => empty_middleware(),
30        1 => middlewares.first().unwrap().clone(),
31        2 => join_middleware(middlewares.get(1).unwrap().clone(), middlewares.get(0).unwrap().clone()),
32        _ => {
33            let inner_most = middlewares.first().unwrap().clone();
34            let mut result = join_middleware(middlewares.get(1).unwrap().clone(), inner_most);
35            for (index, middleware) in middlewares.iter().enumerate() {
36                if index >= 2 {
37                    result = join_middleware(middleware.clone(), result);
38                }
39            }
40            result
41        }
42    }
43}
44
45fn join_middleware(outer: Middleware, inner: Middleware) -> Middleware {
46    Middleware::new(move |req: Request, next: Next| {
47        let outer = outer.clone();
48        let inner = inner.clone();
49        async move {
50            outer.call(req, Next::new(move |req: Request| {
51                let inner = inner.clone();
52                let next = next.clone();
53                async move {
54                    inner.call(req, next).await
55                }
56            })).await
57        }
58    })
59}
60
61pub trait MiddlewareArgument<A>: Send + Sync + 'static {
62    fn call(&self, request: Request, next: Next) -> BoxFuture<'static, teo_result::Result<Response>>;
63}
64
65impl<A0, F, Fut> MiddlewareArgument<(A0,)> for F where
66    A0: ExtractFromRequest + Send + Sync,
67    F: Fn(A0, Next) -> Fut + Sync + Send + Clone + 'static,
68    Fut: Future<Output = teo_result::Result<Response>> + Send + 'static {
69    fn call(&self, request: Request, next: Next) -> BoxFuture<'static, teo_result::Result<Response>> {
70        let value: A0 = ExtractFromRequest::extract(&request);
71        Box::pin(self(value, next))
72    }
73}
74
75impl<A0, A1, F, Fut> MiddlewareArgument<(A0, A1)> for F where
76    A0: ExtractFromRequest + Send + Sync,
77    A1: ExtractFromRequest + Send + Sync,
78    F: Fn(A0, A1, Next) -> Fut + Sync + Send + Clone + 'static,
79    Fut: Future<Output = teo_result::Result<Response>> + Send + 'static {
80    fn call(&self, request: Request, next: Next) -> BoxFuture<'static, teo_result::Result<Response>> {
81        let a0: A0 = ExtractFromRequest::extract(&request);
82        let a1: A1 = ExtractFromRequest::extract(&request);
83        Box::pin(self(a0, a1, next))
84    }
85}
86
87impl<A0, A1, A2, F, Fut> MiddlewareArgument<(A0, A1, A2)> for F where
88    A0: ExtractFromRequest + Send + Sync,
89    A1: ExtractFromRequest + Send + Sync,
90    A2: ExtractFromRequest + Send + Sync,
91    F: Fn(A0, A1, A2, Next) -> Fut + Sync + Send + Clone + 'static,
92    Fut: Future<Output = teo_result::Result<Response>> + Send + 'static {
93    fn call(&self, request: Request, next: Next) -> BoxFuture<'static, teo_result::Result<Response>> {
94        let a0: A0 = ExtractFromRequest::extract(&request);
95        let a1: A1 = ExtractFromRequest::extract(&request);
96        let a2: A2 = ExtractFromRequest::extract(&request);
97        Box::pin(self(a0, a1, a2, next))
98    }
99}
100
101impl<A0, A1, A2, A3, F, Fut> MiddlewareArgument<(A0, A1, A2, A3)> for F where
102    A0: ExtractFromRequest + Send + Sync,
103    A1: ExtractFromRequest + Send + Sync,
104    A2: ExtractFromRequest + Send + Sync,
105    A3: ExtractFromRequest + Send + Sync,
106    F: Fn(A0, A1, A2, A3, Next) -> Fut + Sync + Send + Clone + 'static,
107    Fut: Future<Output = teo_result::Result<Response>> + Send + 'static {
108    fn call(&self, request: Request, next: Next) -> BoxFuture<'static, teo_result::Result<Response>> {
109        let a0: A0 = ExtractFromRequest::extract(&request);
110        let a1: A1 = ExtractFromRequest::extract(&request);
111        let a2: A2 = ExtractFromRequest::extract(&request);
112        let a3: A3 = ExtractFromRequest::extract(&request);
113        Box::pin(self(a0, a1, a2, a3, next))
114    }
115}