1use std::future::Future;
4use std::pin::Pin;
5use std::task::{Context, Poll};
6
7use futures_core::TryFuture;
8use http::{Request, Response};
9use http_body::Body;
10use tower_service::Service;
11
12#[cfg_attr(not(feature = "__docs"), allow(intra_doc_link_resolution_failure))]
13pub trait HttpService<B>: service_private::Sealed<B> {
18 type ResponseBody: Body;
20 type Error;
21 type Future: Future<Output = Result<Response<Self::ResponseBody>, Self::Error>>;
22
23 fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>;
24
25 fn call(&mut self, request: Request<B>) -> Self::Future;
26}
27
28pub trait HttpTryFuture: future_private::Sealed {
32 type Body: Body;
33 type Error;
34
35 fn try_poll(
36 self: Pin<&mut Self>,
37 cx: &mut Context<'_>,
38 ) -> Poll<Result<Response<Self::Body>, Self::Error>>;
39}
40
41impl<F, B> HttpTryFuture for F
42where
43 F: TryFuture<Ok = Response<B>>,
44 B: Body,
45{
46 type Body = B;
47 type Error = F::Error;
48
49 fn try_poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<Response<B>, F::Error>> {
50 self.try_poll(cx)
51 }
52}
53
54impl<F, B> future_private::Sealed for F
55where
56 F: TryFuture<Ok = Response<B>>,
57 B: Body,
58{
59}
60
61impl<S, ReqB, ResB> HttpService<ReqB> for S
62where
63 S: Service<Request<ReqB>, Response = Response<ResB>> + ?Sized,
64 ResB: Body,
65{
66 type ResponseBody = ResB;
67 type Error = S::Error;
68 type Future = S::Future;
69
70 fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
71 Service::poll_ready(self, cx)
72 }
73
74 fn call(&mut self, request: Request<ReqB>) -> S::Future {
75 Service::call(self, request)
76 }
77}
78
79impl<S, ReqB, ResB> service_private::Sealed<ReqB> for S
80where
81 S: Service<Request<ReqB>, Response = Response<ResB>> + ?Sized,
82 ResB: Body,
83{
84}
85
86mod future_private {
87 pub trait Sealed {}
88}
89
90mod service_private {
91 pub trait Sealed<B> {}
92}