1use tower::{Layer, Service, ServiceExt};
2use vidi_core::{Body, BoxError, Bytes, Error, Handler, HttpBody, Request, Response, Result};
3
4use crate::HandlerService;
5
6#[derive(Clone, Debug)]
8pub struct Middleware<L, H> {
9 l: L,
10 h: H,
11}
12
13impl<L, H> Middleware<L, H> {
14 pub const fn new(l: L, h: H) -> Self {
16 Self { l, h }
17 }
18}
19
20#[vidi_core::async_trait]
21impl<O, L, H> Handler<Request> for Middleware<L, H>
22where
23 L: Layer<HandlerService<H>> + Send + Sync + 'static,
24 H: Handler<Request, Output = Result<Response>> + Clone,
25 O: HttpBody + Send + 'static,
26 O::Data: Into<Bytes>,
27 O::Error: Into<BoxError>,
28 L::Service: Service<Request, Response = Response<O>> + Send + Sync + 'static,
29 <L::Service as Service<Request>>::Future: Send,
30 <L::Service as Service<Request>>::Error: Into<BoxError>,
31{
32 type Output = Result<Response>;
33
34 async fn call(&self, req: Request) -> Self::Output {
35 self.l
36 .layer(HandlerService::new(self.h.clone()))
37 .oneshot(req)
38 .await
39 .map_err(Error::boxed)
40 .map(|resp| resp.map(Body::wrap))
41 }
42}