http_body_util/combinators/
collect.rs

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