http_body_util/combinators/
collect.rs

1use std::{
2    future::Future,
3    pin::Pin,
4    task::{Context, Poll},
5};
6
7use futures_core::ready;
8use http_body::Body;
9use pin_project_lite::pin_project;
10
11pin_project! {
12    /// Future that resolves into a [`Collected`].
13    ///
14    /// [`Collected`]: crate::Collected
15    pub struct Collect<T>
16    where
17        T: Body,
18        T: ?Sized,
19    {
20        pub(crate) collected: Option<crate::Collected<T::Data>>,
21        #[pin]
22        pub(crate) body: T,
23    }
24}
25
26impl<T: Body + ?Sized> Future for Collect<T> {
27    type Output = Result<crate::Collected<T::Data>, T::Error>;
28
29    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> std::task::Poll<Self::Output> {
30        let mut me = self.project();
31
32        loop {
33            let frame = ready!(me.body.as_mut().poll_frame(cx));
34
35            let frame = if let Some(frame) = frame {
36                frame?
37            } else {
38                return Poll::Ready(Ok(me.collected.take().expect("polled after complete")));
39            };
40
41            me.collected.as_mut().unwrap().push_frame(frame);
42        }
43    }
44}