mincat-core 0.1.0

Core types and traits for mincat
Documentation
use std::future::Future;

use crate::{
    next::Next,
    request::Request,
    response::{IntoResponse, Response},
};

#[async_trait::async_trait]
pub trait Middleware: Send + Sync {
    async fn call(self: Box<Self>, request: Request, next: Next) -> Response;

    fn clone_box(&self) -> Box<dyn Middleware>;
}

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

pub struct FuncMiddleware<Func>(Func)
where
    Func: MiddlewareFunc;

impl<Func> FuncMiddleware<Func>
where
    Func: MiddlewareFunc,
{
    pub fn from_fn(func: Func) -> Self {
        FuncMiddleware(func)
    }
}

#[async_trait::async_trait]
impl<Func> Middleware for FuncMiddleware<Func>
where
    Func: MiddlewareFunc,
{
    async fn call(self: Box<Self>, request: Request, next: Next) -> Response {
        self.0.call(request, next).await
    }

    fn clone_box(&self) -> Box<dyn Middleware> {
        Box::new(FuncMiddleware(self.0.clone()))
    }
}

#[async_trait::async_trait]
pub trait MiddlewareFunc: Clone + Send + Sync + 'static {
    async fn call(self, request: Request, next: Next) -> Response;
}

#[async_trait::async_trait]
impl<Func, Res, Fut> MiddlewareFunc for Func
where
    Func: FnOnce(Request, Next) -> Fut,
    Func: Clone + Send + Sync + 'static,
    Fut: Future<Output = Res> + Send,
    Res: IntoResponse,
{
    async fn call(self, request: Request, next: Next) -> Response {
        self(request, next).await.into_response()
    }
}