ayun-server 0.23.0

The RUST Framework for Web Rustceans.
Documentation
use crate::{traits::MiddlewareTrait, Middleware};

// https://github.com/tower-rs/tower/issues/496
#[derive(Default)]
pub struct Router {
    inner: axum::Router,
    middlewares: Vec<(String, Middleware)>,
}

impl Router {
    pub fn new() -> Self {
        #[allow(unused_mut)]
        let mut router = Self::default();

        // todo need runtime
        // https://github.com/tokio-rs/axum/issues/2634
        // #[cfg(feature = "middleware-rate-limit")]
        // router = router.middleware::<crate::middleware::RateLimit>();

        #[cfg(feature = "middleware-fallback")]
        {
            router = router.middleware::<crate::middleware::Fallback>();
        }

        #[cfg(feature = "middleware-cors")]
        {
            router = router.middleware::<crate::middleware::Cors>();
        }

        #[cfg(feature = "middleware-body-limit")]
        {
            router = router.middleware::<crate::middleware::BodyLimit>();
        }

        #[cfg(feature = "middleware-asset")]
        {
            router = router.middleware::<crate::middleware::Asset>();
        }

        #[cfg(feature = "middleware-compression")]
        {
            router = router.middleware::<crate::middleware::Compression>();
        }

        #[cfg(feature = "middleware-decompression")]
        {
            router = router.middleware::<crate::middleware::Decompression>();
        }

        #[cfg(feature = "middleware-set-sensitive-request-headers")]
        {
            router = router.middleware::<crate::middleware::SetSensitiveRequestHeaders>();
        }

        #[cfg(feature = "middleware-request-id")]
        {
            router = router.middleware::<crate::middleware::RequestId>();
        }

        #[cfg(feature = "middleware-logger")]
        {
            router = router.middleware::<crate::middleware::Logger>();
        }

        #[cfg(feature = "middleware-catch-panic")]
        {
            router = router.middleware::<crate::middleware::CatchPanic>();
        }

        #[cfg(feature = "middleware-timeout")]
        {
            router = router.middleware::<crate::middleware::Timeout>();
        }

        router
    }

    pub fn route(mut self, path: &str, method_router: axum::routing::MethodRouter<()>) -> Self {
        self.inner = self.inner.route(path, method_router);

        self
    }

    pub fn middleware<T: MiddlewareTrait>(mut self) -> Self {
        self.middlewares.push((T::name(), T::handle()));

        self
    }
}

impl From<Router> for axum::Router {
    fn from(mut value: Router) -> Self {
        let mut router = value.inner;
        let mut middlewares = vec![];

        while let Some((name, layer)) = value.middlewares.pop() {
            router = layer(router)
                .unwrap_or_else(|err| panic!("[middleware] `{name}` applied error: {err}"));

            middlewares.push(name);
        }

        while let Some(middleware) = middlewares.pop() {
            tracing::info!("[middleware] `{middleware}` successfully applied"); // todo different route may has different middlewares
        }

        router
    }
}