use async_trait::async_trait;
use std::sync::Arc;
use crate::core::{Request, Response, router::Handler};
#[async_trait]
pub trait Middleware: Send + Sync + 'static {
async fn handle(&self, req: Request, next: Arc<dyn Handler>) -> Response;
}
struct MiddlewareHandler {
middleware: Arc<dyn Middleware>,
next: Arc<dyn Handler>,
}
#[async_trait]
impl Handler for MiddlewareHandler {
async fn handle(&self, req: Request) -> Response {
self.middleware.handle(req, Arc::clone(&self.next)).await
}
}
pub fn compose(
middlewares: &[Arc<dyn Middleware>],
final_handler: Arc<dyn Handler>,
) -> Arc<dyn Handler> {
let mut current_handler = final_handler;
for i in (0..middlewares.len()).rev() {
let middleware = Arc::clone(&middlewares[i]);
let next_handler = Arc::clone(¤t_handler);
current_handler = Arc::new(MiddlewareHandler {
middleware,
next: next_handler,
});
}
current_handler
}