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}