use super::body::create_error_response; use super::ResponseBody; use http::Response; use http_body::Body; use pin_project_lite::pin_project; use std::future::Future; use std::pin::Pin; use std::task::{ready, Context, Poll}; pin_project! { /// Response future for [`RequestBodyLimit`]. /// /// [`RequestBodyLimit`]: super::RequestBodyLimit pub struct ResponseFuture { #[pin] inner: ResponseFutureInner, } } impl ResponseFuture { pub(crate) fn payload_too_large() -> Self { Self { inner: ResponseFutureInner::PayloadTooLarge, } } pub(crate) fn new(future: F) -> Self { Self { inner: ResponseFutureInner::Future { future }, } } } pin_project! { #[project = ResFutProj] enum ResponseFutureInner { PayloadTooLarge, Future { #[pin] future: F, } } } impl Future for ResponseFuture where ResBody: Body, F: Future, E>>, { type Output = Result>, E>; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let res = match self.project().inner.project() { ResFutProj::PayloadTooLarge => create_error_response(), ResFutProj::Future { future } => ready!(future.poll(cx))?.map(ResponseBody::new), }; Poll::Ready(Ok(res)) } }