Skip to main content

sword_core/
layer_stack.rs

1use axum::{Router, extract::Request, response::IntoResponse, routing::Route};
2use std::convert::Infallible;
3use tower::{Layer, Service};
4
5type LayerFn<S> = Box<dyn Fn(Router<S>) -> Router<S> + Send + Sync>;
6
7/// A stack for managing and applying middleware layers to a router.
8///
9/// `LayerStack` provides a way to accumulate layers and apply them to a router in the
10/// order they were added. Layers are applied via the `push()` method during configuration,
11/// and then applied to the router via `apply()` during the build phase.
12pub struct LayerStack<S> {
13    layers: Vec<LayerFn<S>>,
14}
15
16impl<S> LayerStack<S>
17where
18    S: Clone + Send + Sync + 'static,
19{
20    pub fn new() -> Self {
21        Self { layers: Vec::new() }
22    }
23
24    /// Add a layer to the stack.
25    ///
26    /// Layers are applied in FIFO order when `apply()` is called. Each layer will
27    /// wrap the router after all controllers have been registered.
28    pub fn push<L>(&mut self, layer: L)
29    where
30        L: Layer<Route> + Clone + Send + Sync + 'static,
31        L::Service: Service<Request> + Clone + Send + Sync + 'static,
32        <L::Service as Service<Request>>::Response: IntoResponse + 'static,
33        <L::Service as Service<Request>>::Error: Into<Infallible> + 'static,
34        <L::Service as Service<Request>>::Future: Send + 'static,
35    {
36        self.layers.push(Box::new(move |router: Router<S>| {
37            router.layer(layer.clone())
38        }));
39    }
40
41    /// Apply all layers to the given router.
42    ///
43    /// Layers are applied in FIFO order (first pushed = first applied = outermost).
44    pub fn apply(&self, mut router: Router<S>) -> Router<S> {
45        for layer_fn in self.layers.iter() {
46            router = layer_fn(router);
47        }
48        router
49    }
50}
51
52impl<S> Default for LayerStack<S>
53where
54    S: Clone + Send + Sync + 'static,
55{
56    fn default() -> Self {
57        Self::new()
58    }
59}