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)] |
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 | |
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 | |
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 | |
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 | |