1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
use crate::{handler::Handler, regex::Rule, request::Request, response::Response, Result};
use async_recursion::async_recursion;
use async_trait::async_trait;
use std::{future::Future, sync::Arc};

#[async_trait]
pub trait Middleware: Send + Sync + 'static {
    #[must_use]
    async fn hook(&self, req: Request, next: Next) -> Result<Response>;
}

#[async_trait]
impl<F, Fut> Middleware for F
where
    Fut: Future<Output = Result<Response>> + 'static + Send,
    F: Send + Sync + 'static + Fn(Request, Next) -> Fut,
{
    async fn hook(&self, req: Request, next: Next) -> Result<Response> {
        self(req, next).await
    }
}

#[derive(Clone)]
pub struct Next {
    pub(crate) path: String,
    pub(crate) middleware: Vec<(Rule, Arc<dyn Middleware>)>,
    pub(crate) handler: Arc<dyn Handler>,
}

impl Next {
    #[inline]
    #[async_recursion]
    pub async fn next(self, req: Request) -> Result<Response> {
        match self.middleware.split_first() {
            Some((head, middleware)) => {
                let next = Next {
                    path: self.path,
                    handler: self.handler.clone(),
                    middleware: middleware.to_vec(),
                };
                let (rule, mid) = head;
                if rule.validate_path(&next.path) {
                    mid.hook(req, next).await
                } else {
                    next.next(req).await
                }
            }
            None => self.handler.handle(req).await,
        }
    }
}