kit_rs/middleware/
registry.rs

1//! Middleware registry for global middleware
2//!
3//! Configure global middleware in `bootstrap.rs` using the `global_middleware!` macro,
4//! or use `Server::middleware()` for manual configuration.
5
6use super::{into_boxed, BoxedMiddleware, Middleware};
7use std::sync::{OnceLock, RwLock};
8
9/// Global middleware registry (populated via `global_middleware!` macro in bootstrap.rs)
10static GLOBAL_MIDDLEWARE: OnceLock<RwLock<Vec<BoxedMiddleware>>> = OnceLock::new();
11
12/// Register a global middleware that runs on every request
13///
14/// Called by the `global_middleware!` macro. Middleware runs in registration order.
15///
16/// # Example
17///
18/// ```rust,ignore
19/// // In bootstrap.rs
20/// global_middleware!(LoggingMiddleware);
21/// global_middleware!(CorsMiddleware);
22/// ```
23pub fn register_global_middleware<M: Middleware + 'static>(middleware: M) {
24    let registry = GLOBAL_MIDDLEWARE.get_or_init(|| RwLock::new(Vec::new()));
25    if let Ok(mut vec) = registry.write() {
26        vec.push(into_boxed(middleware));
27    }
28}
29
30/// Get all registered global middleware
31///
32/// Used internally by `Server::from_config()` to apply middleware.
33pub fn get_global_middleware() -> Vec<BoxedMiddleware> {
34    GLOBAL_MIDDLEWARE
35        .get()
36        .and_then(|lock| lock.read().ok())
37        .map(|vec| vec.clone())
38        .unwrap_or_default()
39}
40
41/// Registry for global middleware that runs on every request
42///
43/// # Example
44///
45/// ```rust,ignore
46/// Server::from_config(router)
47///     .middleware(LoggingMiddleware)  // Global middleware
48///     .middleware(CorsMiddleware)
49///     .run()
50///     .await;
51/// ```
52pub struct MiddlewareRegistry {
53    /// Middleware that runs on every request (in order)
54    global: Vec<BoxedMiddleware>,
55}
56
57impl MiddlewareRegistry {
58    /// Create a new empty middleware registry
59    pub fn new() -> Self {
60        Self {
61            global: Vec::new(),
62        }
63    }
64
65    /// Create a registry pre-populated with globally registered middleware
66    ///
67    /// This pulls middleware registered via `global_middleware!` in bootstrap.rs.
68    pub fn from_global() -> Self {
69        Self {
70            global: get_global_middleware(),
71        }
72    }
73
74    /// Append global middleware that runs on every request
75    ///
76    /// Global middleware runs in the order they are added, before any
77    /// route-specific middleware.
78    ///
79    /// # Example
80    ///
81    /// ```rust,ignore
82    /// m.append(LoggingMiddleware)
83    ///  .append(CorsMiddleware)
84    /// ```
85    pub fn append<M: Middleware + 'static>(mut self, middleware: M) -> Self {
86        self.global.push(into_boxed(middleware));
87        self
88    }
89
90    /// Get the list of global middleware
91    pub fn global_middleware(&self) -> &[BoxedMiddleware] {
92        &self.global
93    }
94}
95
96impl Default for MiddlewareRegistry {
97    fn default() -> Self {
98        Self::new()
99    }
100}