Skip to main content

bimp_net/
body.rs

1use std::pin::Pin;
2use std::task::{Context, Poll};
3
4use bytes::Bytes;
5use hyper::body::{Body as HyperBody, Frame, SizeHint};
6use tokio::sync::mpsc;
7
8use crate::error::Error as NetError;
9
10/// Streaming response body returned by [`crate::Client::send`].
11///
12/// The body implements [`hyper::body::Body`] and yields decoded response bytes
13/// as `Bytes` frames.
14pub struct Body {
15    pub(crate) receiver: mpsc::Receiver<Result<Bytes, NetError>>,
16}
17
18impl Body {
19    /// Creates a body from the internal curl transfer channel.
20    pub(crate) fn new(receiver: mpsc::Receiver<Result<Bytes, NetError>>) -> Self {
21        Self { receiver }
22    }
23}
24
25impl HyperBody for Body {
26    /// The data frame type yielded by this body.
27    type Data = Bytes;
28    /// The error type yielded if the curl transfer fails while streaming.
29    type Error = NetError;
30
31    /// Polls the next response body frame.
32    fn poll_frame(
33        mut self: Pin<&mut Self>,
34        cx: &mut Context<'_>,
35    ) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> {
36        match self.receiver.poll_recv(cx) {
37            Poll::Ready(Some(Ok(bytes))) => Poll::Ready(Some(Ok(Frame::data(bytes)))),
38            Poll::Ready(Some(Err(error))) => Poll::Ready(Some(Err(error))),
39            Poll::Ready(None) => Poll::Ready(None),
40            Poll::Pending => Poll::Pending,
41        }
42    }
43
44    /// Returns the response body size hint.
45    fn size_hint(&self) -> SizeHint {
46        SizeHint::default()
47    }
48}