sfo_http/http_server/
endpoint.rs

1use std::future::Future;
2use std::net::Incoming;
3use std::sync::Arc;
4use async_trait::async_trait;
5use crate::errors::HttpResult;
6use super::{Endpoint, Request, Response, Middleware, Next};
7
8pub type DynEndpoint<Req, Resp> = dyn Endpoint<Req, Resp>;
9
10pub(crate) struct MiddlewareEndpoint<E, Req: Request, Resp: Response> {
11    endpoint: E,
12    middleware: Vec<Arc<dyn Middleware<Req, Resp>>>,
13}
14
15impl<E: Clone, Req: Request, Resp: Response> Clone for MiddlewareEndpoint<E, Req, Resp> {
16    fn clone(&self) -> Self {
17        Self {
18            endpoint: self.endpoint.clone(),
19            middleware: self.middleware.clone(),
20        }
21    }
22}
23
24impl<E, Req: Request, Resp: Response> std::fmt::Debug for MiddlewareEndpoint<E, Req, Resp> {
25    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26        write!(
27            fmt,
28            "MiddlewareEndpoint (length: {})",
29            self.middleware.len(),
30        )
31    }
32}
33
34impl<E, Req: Request, Resp: Response> MiddlewareEndpoint<E, Req, Resp>
35where
36    E: Endpoint<Req, Resp>,
37{
38    pub(crate) fn wrap_with_middleware(
39        ep: E,
40        middleware: &[Arc<dyn Middleware<Req, Resp>>],
41    ) -> Box<dyn Endpoint<Req, Resp> + Send + Sync + 'static> {
42        if middleware.is_empty() {
43            Box::new(ep)
44        } else {
45            Box::new(Self {
46                endpoint: ep,
47                middleware: middleware.to_vec(),
48            })
49        }
50    }
51}
52
53#[async_trait]
54impl<E, Req: Request, Resp: Response> Endpoint<Req, Resp> for MiddlewareEndpoint<E, Req, Resp>
55where
56    E: Endpoint<Req, Resp>,
57{
58    async fn call(&self, req: Req) -> HttpResult<Resp> {
59        let next = Next {
60            endpoint: &self.endpoint,
61            next_middleware: &self.middleware,
62        };
63        Ok(next.run(req).await)
64    }
65}
66
67#[async_trait]
68impl<Req: Request, Resp: Response> Endpoint<Req, Resp> for Box<dyn Endpoint<Req, Resp>> {
69    async fn call(&self, request: Req) -> HttpResult<Resp> {
70        self.as_ref().call(request).await
71    }
72}