http_body_alt/body.rs
1use core::{
2 ops::{Deref, DerefMut},
3 pin::Pin,
4 task::{Context, Poll},
5};
6
7use super::{frame::Frame, size_hint::SizeHint};
8
9type Result<T, E> = std::result::Result<Frame<T>, E>;
10
11/// An asynchronous streaming body composed of [`Frame`]s.
12///
13/// Each frame is either a [`Frame::Data`] carrying payload bytes or a [`Frame::Trailers`]
14/// carrying trailing headers. The stream signals completion by returning `Poll::Ready(None)`.
15pub trait Body {
16 /// The payload data type yielded by [`Frame::Data`] variants.
17 type Data;
18 /// The error type that can occur while producing frames.
19 type Error;
20
21 /// Attempt to pull the next frame from the body.
22 ///
23 /// # Return values
24 ///
25 /// - `Poll::Pending` — the next frame is not yet available.
26 /// - `Poll::Ready(Some(Ok(frame)))` — a [`Frame::Data`] or [`Frame::Trailers`] frame.
27 /// - `Poll::Ready(Some(Err(e)))` — a terminal error; no further frames will be produced.
28 /// - `Poll::Ready(None)` — the body is fully consumed.
29 fn poll_frame(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Result<Self::Data, Self::Error>>>;
30
31 /// Indicates whether the body has been fully consumed.
32 ///
33 /// - `true` — the body is exhausted and [`Body::poll_frame`] should not be called again.
34 /// - `false` — the body may still have frames to yield, or its state is unknown.
35 ///
36 /// Implementors SHOULD override this method when possible. Accurate reporting improves
37 /// correctness and performance of consumers that can skip polling when the body is empty.
38 #[inline]
39 fn is_end_stream(&self) -> bool {
40 false
41 }
42
43 /// Returns a hint about the total size of the remaining [`Frame::Data`] payload.
44 ///
45 /// The hint applies only to data frames; trailer frames are not included.
46 ///
47 /// Implementors SHOULD override this method when possible. An accurate size hint allows
48 /// consumers to pre-allocate buffers and set content-length headers.
49 #[inline]
50 fn size_hint(&self) -> SizeHint {
51 SizeHint::default()
52 }
53}
54
55impl<B> Body for Box<B>
56where
57 B: Body + ?Sized + Unpin,
58{
59 type Data = B::Data;
60 type Error = B::Error;
61
62 #[inline]
63 fn poll_frame(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Result<Self::Data, Self::Error>>> {
64 Body::poll_frame(Pin::new(self.get_mut().deref_mut()), cx)
65 }
66
67 #[inline]
68 fn is_end_stream(&self) -> bool {
69 self.deref().is_end_stream()
70 }
71
72 #[inline]
73 fn size_hint(&self) -> SizeHint {
74 self.deref().size_hint()
75 }
76}
77
78impl<B> Body for Pin<B>
79where
80 B: DerefMut,
81 B::Target: Body,
82{
83 type Data = <B::Target as Body>::Data;
84 type Error = <B::Target as Body>::Error;
85
86 #[inline]
87 fn poll_frame(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Result<Self::Data, Self::Error>>> {
88 Body::poll_frame(self.as_deref_mut(), cx)
89 }
90
91 #[inline]
92 fn is_end_stream(&self) -> bool {
93 self.as_ref().is_end_stream()
94 }
95
96 #[inline]
97 fn size_hint(&self) -> SizeHint {
98 self.as_ref().size_hint()
99 }
100}