satex_service/
lib.rs

1#![doc = include_str!("../README.md")]
2
3pub mod echo;
4pub mod make;
5pub mod proxy;
6pub mod serve_dir;
7pub mod status_code;
8
9use bytes::Bytes;
10use futures::future::LocalBoxFuture;
11use http::{Request, Response};
12use satex_core::body::Body;
13use satex_core::util::{try_downcast, SyncBoxCloneService};
14use satex_core::{BoxError, Error};
15use std::task::{Context, Poll};
16use tower::{Service, ServiceExt};
17
18#[derive(Clone)]
19pub struct RouteService(SyncBoxCloneService<Request<Body>, Response<Body>, Error>);
20
21impl RouteService {
22    pub fn new<S, E, ResBody>(service: S) -> Self
23    where
24        S: Service<Request<Body>, Response=Response<ResBody>, Error=E>
25            + Clone
26            + Send
27            + Sync
28            + 'static,
29        E: Into<BoxError>,
30        ResBody: http_body::Body<Data = Bytes> + Send + 'static,
31        ResBody::Error: Into<BoxError>,
32    {
33        try_downcast::<RouteService, _>(service).unwrap_or_else(|service| {
34            Self(SyncBoxCloneService::new(
35                service
36                    .map_response(|response| response.map(Body::new))
37                    .map_err(|e| Error::new(e.into())),
38            ))
39        })
40    }
41}
42
43impl<ReqBody> Service<Request<ReqBody>> for RouteService
44where
45    ReqBody: http_body::Body<Data = Bytes> + Send + 'static,
46    ReqBody::Error: Into<BoxError>,
47{
48    type Response = Response<Body>;
49    type Error = Error;
50    type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;
51
52    fn poll_ready(&mut self, ctx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
53        self.0.poll_ready(ctx)
54    }
55
56    fn call(&mut self, request: Request<ReqBody>) -> Self::Future {
57        self.0.call(request.map(Body::new))
58    }
59}