//! [`Service`](tower::Service) future types. use crate::{ body::{box_body, BoxBody}, util::{Either, EitherProj}, BoxError, }; 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; use tower_service::Service; 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>; 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)) } } }