use std::{ future::Future, pin::Pin, task::{Context, Poll}, }; use futures_core::ready; use http_body::Body; use pin_project_lite::pin_project; pin_project! { /// Future that resolves into a [`Collected`]. /// /// [`Collected`]: crate::Collected pub struct Collect where T: Body, T: ?Sized, { pub(crate) collected: Option>, #[pin] pub(crate) body: T, } } impl Future for Collect { type Output = Result, T::Error>; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> std::task::Poll { let mut me = self.project(); loop { let frame = ready!(me.body.as_mut().poll_frame(cx)); let frame = if let Some(frame) = frame { frame? } else { return Poll::Ready(Ok(me.collected.take().expect("polled after complete"))); }; me.collected.as_mut().unwrap().push_frame(frame); } } }