use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};
use futures_core::TryFuture;
use http::{Request, Response};
use http_body::Body;
use tower_service::Service;
#[cfg_attr(not(feature = "__docs"), allow(intra_doc_link_resolution_failure))]
pub trait HttpService<B>: service_private::Sealed<B> {
type ResponseBody: Body;
type Error;
type Future: Future<Output = Result<Response<Self::ResponseBody>, Self::Error>>;
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>;
fn call(&mut self, request: Request<B>) -> Self::Future;
}
pub trait HttpTryFuture: future_private::Sealed {
type Body: Body;
type Error;
fn try_poll(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Result<Response<Self::Body>, Self::Error>>;
}
impl<F, B> HttpTryFuture for F
where
F: TryFuture<Ok = Response<B>>,
B: Body,
{
type Body = B;
type Error = F::Error;
fn try_poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<Response<B>, F::Error>> {
self.try_poll(cx)
}
}
impl<F, B> future_private::Sealed for F
where
F: TryFuture<Ok = Response<B>>,
B: Body,
{
}
impl<S, ReqB, ResB> HttpService<ReqB> for S
where
S: Service<Request<ReqB>, Response = Response<ResB>> + ?Sized,
ResB: Body,
{
type ResponseBody = ResB;
type Error = S::Error;
type Future = S::Future;
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
Service::poll_ready(self, cx)
}
fn call(&mut self, request: Request<ReqB>) -> S::Future {
Service::call(self, request)
}
}
impl<S, ReqB, ResB> service_private::Sealed<ReqB> for S
where
S: Service<Request<ReqB>, Response = Response<ResB>> + ?Sized,
ResB: Body,
{
}
mod future_private {
pub trait Sealed {}
}
mod service_private {
pub trait Sealed<B> {}
}