//! [`Service`](tower::Service) future types. use crate::{ body::{box_body, BoxBody}, response::IntoResponse, util::{Either, EitherProj}, }; use bytes::Bytes; use futures_util::ready; use http::{Method, Request, Response}; use http_body::Empty; use pin_project_lite::pin_project; use std::{ future::Future, pin::Pin, task::{Context, Poll}, }; use tower::{util::Oneshot, BoxError, Service}; pin_project! { /// Response future for [`HandleError`](super::HandleError). #[derive(Debug)] pub struct HandleErrorFuture { #[pin] pub(super) inner: Fut, pub(super) f: Option, } } impl Future for HandleErrorFuture where Fut: Future, E>>, F: FnOnce(E) -> Result, Res: IntoResponse, B: http_body::Body + Send + Sync + 'static, B::Error: Into + Send + Sync + 'static, { type Output = Result, E2>; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = self.project(); match ready!(this.inner.poll(cx)) { Ok(res) => Ok(res.map(box_body)).into(), Err(err) => { let f = this.f.take().unwrap(); match f(err) { Ok(res) => Ok(res.into_response().map(box_body)).into(), Err(err) => Err(err).into(), } } } } } pin_project! { /// The response future for [`OnMethod`](super::OnMethod). pub struct OnMethodFuture where S: Service>, F: Service> { #[pin] pub(super) inner: Either< Oneshot>, Oneshot>, >, // pub(super) inner: crate::routing::future::RouteFuture, pub(super) req_method: Method, } } impl Future for OnMethodFuture where S: Service, Response = Response> + Clone, ResBody: http_body::Body + Send + Sync + 'static, ResBody::Error: Into, F: Service, Response = Response, Error = S::Error>, { type Output = Result, S::Error>; #[allow(warnings)] fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let this = self.project(); let response = match this.inner.project() { EitherProj::A { inner } => ready!(inner.poll(cx))?.map(box_body), EitherProj::B { inner } => ready!(inner.poll(cx))?, }; if this.req_method == &Method::HEAD { let response = response.map(|_| box_body(Empty::new())); Poll::Ready(Ok(response)) } else { Poll::Ready(Ok(response)) } } }