axeon 0.2.0

A modern and flexible backend server framework for Rust
Documentation
mod security;
mod compression;

use crate::http::Request;
pub use security::{RateLimitConfig, RateLimiter, SecurityConfig, SecurityHeaders, CorsConfig, Cors};
pub use compression::{CompressionConfig, CompressionMiddleware};

use crate::handler::{Handler, HttpResponse, IntoResponse};
use futures::future::BoxFuture;

#[derive(Clone)]
pub struct Next {
    handler: Box<dyn Handler>,
}

impl Next {
    pub fn new<F, R>(handler: F) -> Self
    where
        F: Fn(Request) -> R + Send + Sync + Clone + 'static,
        R: IntoResponse,

    {
        Self {
            handler: Box::new(handler),
        }
    }

    pub(crate) fn new_handler(handler: Box<dyn Handler>) -> Self {
        Self { handler}
    }

    pub async fn handle(&self, req: Request) -> HttpResponse {
        self.handler.handle(req).await
    }
}

pub type MiddlewareResult = BoxFuture<'static, HttpResponse>;


pub trait Middleware: Send + Sync + 'static {
    fn call(&self, req: Request, next: Next) -> MiddlewareResult;
    fn clone_box(&self) -> Box<dyn Middleware>;
}

impl Clone for Box<dyn Middleware> {
    fn clone(&self) -> Box<dyn Middleware> {
        self.clone_box()
    }
}

#[derive(Clone)]
pub(crate) struct MiddlewareManager {
    pub(crate )middlewares: Vec<Box<dyn Middleware>>,
}


impl MiddlewareManager {
    pub fn new() -> Self {
        Self {
            middlewares: Vec::new(),
        }
    }

    pub fn add<M: Middleware + 'static>(&mut self, middleware: M) {
        self.middlewares.push(Box::new(middleware));
    }

    pub fn append(&mut self, mut other: MiddlewareManager) -> &Self {
        self.middlewares.append(&mut other.middlewares);
        self
    }

    pub async fn call(&self, req: Request, next: Next) -> HttpResponse {
        let mut next = next;
        let mut index = self.middlewares.len();
        while index > 0 {
            index -= 1;
            let middleware = self.middlewares[index].clone();
            next = Next::new_handler(Box::new(move |req| middleware.call(req, next.clone())));
        }
        next.handle(req).await
    }

}


#[macro_export]
macro_rules! middlewares {
    ($handler:expr) => {
       $handler
    };

    ($middleware:expr, $handler:expr) => {
        |req| {
            $middleware.call(req, axeon::middleware::Next::new($handler))
        }
    };

    ($middleware:expr, $($rest:tt)*) => {
        |req| {
            $middleware.call(req, axeon::middleware::Next::new(middlewares!($($rest)*)))
        }
    };

    () => {
        compile_error!("The middlewares! macro requires at least one handler")
    };
}