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