1 use std::error::Error as StdError;
2 use std::future::Future;
3 use std::task::{Context, Poll};
4 
5 use crate::body::HttpBody;
6 use crate::{Request, Response};
7 
8 /// An asynchronous function from `Request` to `Response`.
9 pub trait HttpService<ReqBody>: sealed::Sealed<ReqBody> {
10     /// The `HttpBody` body of the `http::Response`.
11     type ResBody: HttpBody;
12 
13     /// The error type that can occur within this `Service`.
14     ///
15     /// Note: Returning an `Error` to a hyper server will cause the connection
16     /// to be abruptly aborted. In most cases, it is better to return a `Response`
17     /// with a 4xx or 5xx status code.
18     type Error: Into<Box<dyn StdError + Send + Sync>>;
19 
20     /// The `Future` returned by this `Service`.
21     type Future: Future<Output = Result<Response<Self::ResBody>, Self::Error>>;
22 
23     #[doc(hidden)]
poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>24     fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>;
25 
26     #[doc(hidden)]
call(&mut self, req: Request<ReqBody>) -> Self::Future27     fn call(&mut self, req: Request<ReqBody>) -> Self::Future;
28 }
29 
30 impl<T, B1, B2> HttpService<B1> for T
31 where
32     T: tower_service::Service<Request<B1>, Response = Response<B2>>,
33     B2: HttpBody,
34     T::Error: Into<Box<dyn StdError + Send + Sync>>,
35 {
36     type ResBody = B2;
37 
38     type Error = T::Error;
39     type Future = T::Future;
40 
poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>41     fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
42         tower_service::Service::poll_ready(self, cx)
43     }
44 
call(&mut self, req: Request<B1>) -> Self::Future45     fn call(&mut self, req: Request<B1>) -> Self::Future {
46         tower_service::Service::call(self, req)
47     }
48 }
49 
50 impl<T, B1, B2> sealed::Sealed<B1> for T
51 where
52     T: tower_service::Service<Request<B1>, Response = Response<B2>>,
53     B2: HttpBody,
54 {
55 }
56 
57 mod sealed {
58     pub trait Sealed<T> {}
59 }
60