use reinhardt_core::exception::Result;
use reinhardt_http::{Handler, Request, Response};
use reinhardt_middleware::Middleware;
use std::sync::Arc;
pub struct MiddlewareChain {
handler: Arc<dyn Handler>,
middlewares: Vec<Arc<dyn Middleware>>,
}
impl MiddlewareChain {
pub fn new(handler: Arc<dyn Handler>) -> Self {
Self {
handler,
middlewares: Vec::new(),
}
}
pub fn add_middleware(mut self, middleware: Arc<dyn Middleware>) -> Self {
self.middlewares.push(middleware);
self
}
pub fn build(self) -> Arc<dyn Handler> {
let mut handler = self.handler;
for middleware in self.middlewares.into_iter().rev() {
handler = Arc::new(MiddlewareHandler {
middleware,
next: handler,
});
}
handler
}
}
struct MiddlewareHandler {
middleware: Arc<dyn Middleware>,
next: Arc<dyn Handler>,
}
#[async_trait::async_trait]
impl Handler for MiddlewareHandler {
async fn handle(&self, request: Request) -> Result<Response> {
self.middleware.process(request, self.next.clone()).await
}
}