Skip to main content

httpward_core/httpward_middleware/
next.rs

1// httpward-core/src/httpward_middleware/next.rs
2
3use std::sync::Arc;
4use crate::httpward_middleware::types::BoxError;
5use crate::httpward_middleware::middleware_trait::HttpWardMiddleware;
6use rama::http::{Body, Request, Response};
7use rama::Context;
8use crate::httpward_middleware::types::BoxService;
9
10pub struct Next<'a> {
11    middlewares: &'a [Arc<dyn HttpWardMiddleware>],
12    index: usize,
13    inner: &'a BoxService,
14}
15
16impl<'a> Next<'a> {
17    pub fn new(
18        middlewares: &'a [Arc<dyn HttpWardMiddleware>],
19        inner: &'a BoxService,
20    ) -> Self {
21        Self {
22            middlewares,
23            index: 0,
24            inner,
25        }
26    }
27
28    fn advance(&self) -> Self {
29        Self {
30            middlewares: self.middlewares,
31            index: self.index + 1,
32            inner: self.inner,
33        }
34    }
35
36    pub async fn run(
37        self,
38        ctx: Context<()>,
39        req: Request<Body>,
40    ) -> Result<Response<Body>, BoxError> {
41
42        if let Some(mw_box) = self.middlewares.get(self.index) {
43
44            let middleware = mw_box.as_ref();
45            let next = self.advance();
46
47            middleware.handle(ctx, req, next).await
48
49        } else {
50
51            // Call the inner service as a function since BoxService is a Fn
52            (self.inner)(ctx, req).await
53        }
54    }
55}