Skip to main content

rustbasic_core/middleware/
mod.rs

1pub mod logging;
2pub mod security_headers;
3
4use std::sync::Arc;
5use std::pin::Pin;
6use crate::requests::Request;
7use crate::router::{Response, ErasedHandler};
8
9pub type MiddlewareFn = Arc<
10    dyn Fn(Request, Next) -> Pin<Box<dyn std::future::Future<Output = Response> + Send>>
11        + Send
12        + Sync,
13>;
14
15pub struct Next {
16    pub(crate) chain: Arc<MiddlewareChain>,
17}
18
19impl Next {
20    pub async fn run(self, req: Request) -> Response {
21        self.chain.next(req).await
22    }
23}
24
25pub enum MiddlewareChain {
26    Next(MiddlewareFn, Arc<MiddlewareChain>),
27    End(Arc<dyn ErasedHandler>),
28}
29
30impl MiddlewareChain {
31    pub async fn next(self: Arc<Self>, req: Request) -> Response {
32        match &*self {
33            Self::Next(mw, next_chain) => {
34                let next = Next { chain: next_chain.clone() };
35                mw(req, next).await
36            }
37            Self::End(handler) => {
38                handler.call(req).await
39            }
40        }
41    }
42}
43
44pub fn from_fn<F, Fut>(mw: F) -> MiddlewareFn
45where
46    F: Fn(Request, Next) -> Fut + Send + Sync + 'static,
47    Fut: std::future::Future<Output = Response> + Send + 'static,
48{
49    Arc::new(move |req, next| Box::pin(mw(req, next)))
50}