1use std::error::Error as StdError;
2use std::future::Future;
3use std::task::{Context, Poll};
4
5use crate::body::HttpBody;
6use crate::{Request, Response};
7
8/// An asynchronous function from `Request` to `Response`.
9pub 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)]
24 fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>;
25
26 #[doc(hidden)]
27 fn call(&mut self, req: Request<ReqBody>) -> Self::Future;
28}
29
30impl<T, B1, B2> HttpService<B1> for T
31where
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
41 fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
42 tower_service::Service::poll_ready(self, cx)
43 }
44
45 fn call(&mut self, req: Request<B1>) -> Self::Future {
46 tower_service::Service::call(self, req)
47 }
48}
49
50impl<T, B1, B2> sealed::Sealed<B1> for T
51where
52 T: tower_service::Service<Request<B1>, Response = Response<B2>>,
53 B2: HttpBody,
54{
55}
56
57mod sealed {
58 pub trait Sealed<T> {}
59}
60