kit_rs/middleware/
chain.rs

1//! Middleware chain execution engine
2
3use super::{BoxedMiddleware, MiddlewareFuture, Next};
4use crate::http::{Request, Response};
5use crate::routing::BoxedHandler;
6use std::sync::Arc;
7
8/// Builds and executes the middleware chain
9///
10/// The chain is built from the outside-in:
11/// 1. Global middleware (first to run)
12/// 2. Route group middleware
13/// 3. Route-level middleware
14/// 4. The actual route handler (innermost)
15pub struct MiddlewareChain {
16    middleware: Vec<BoxedMiddleware>,
17}
18
19impl MiddlewareChain {
20    /// Create a new empty middleware chain
21    pub fn new() -> Self {
22        Self {
23            middleware: Vec::new(),
24        }
25    }
26
27    /// Add middleware to the chain
28    ///
29    /// Middleware are executed in the order they are added.
30    pub fn push(&mut self, middleware: BoxedMiddleware) {
31        self.middleware.push(middleware);
32    }
33
34    /// Add multiple middleware to the chain
35    pub fn extend(&mut self, middleware: impl IntoIterator<Item = BoxedMiddleware>) {
36        self.middleware.extend(middleware);
37    }
38
39    /// Execute the middleware chain with the given request and final handler
40    ///
41    /// The chain is executed from outside-in:
42    /// - First middleware added runs first
43    /// - Each middleware can call `next(request)` to continue the chain
44    /// - The final handler is called at the end of the chain
45    pub async fn execute(self, request: Request, handler: Arc<BoxedHandler>) -> Response {
46        if self.middleware.is_empty() {
47            // No middleware - call handler directly
48            return handler(request).await;
49        }
50
51        // Build the chain from inside-out
52        // Start with the actual handler as the innermost "next"
53        let handler_clone = handler.clone();
54        let mut next: Next = Arc::new(move |req| handler_clone(req));
55
56        // Wrap each middleware around the next, from last to first
57        // This creates the correct execution order: first middleware runs first
58        for middleware in self.middleware.into_iter().rev() {
59            let current_next = next;
60            let mw = middleware;
61            next = Arc::new(move |req| {
62                let n = current_next.clone();
63                let m = mw.clone();
64                Box::pin(async move { m(req, n).await }) as MiddlewareFuture
65            });
66        }
67
68        // Execute the outermost middleware (which was the first added)
69        next(request).await
70    }
71}
72
73impl Default for MiddlewareChain {
74    fn default() -> Self {
75        Self::new()
76    }
77}