1#![deny(
2 missing_debug_implementations,
3 missing_docs,
4 unreachable_pub,
5 clippy::missing_safety_doc,
6 clippy::undocumented_unsafe_blocks
7)]
8#![cfg_attr(test, deny(warnings))]
9
10mod frame;
17mod size_hint;
18
19pub use self::frame::Frame;
20pub use self::size_hint::SizeHint;
21
22use bytes::{Buf, Bytes};
23use std::convert::Infallible;
24use std::ops;
25use std::pin::Pin;
26use std::task::{Context, Poll};
27
28pub trait Body {
39 type Data: Buf;
41
42 type Error;
44
45 #[allow(clippy::type_complexity)]
46 fn poll_frame(
63 self: Pin<&mut Self>,
64 cx: &mut Context<'_>,
65 ) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>>;
66
67 fn is_end_stream(&self) -> bool {
78 false
79 }
80
81 fn size_hint(&self) -> SizeHint {
86 SizeHint::default()
87 }
88}
89
90impl<T: Body + Unpin + ?Sized> Body for &mut T {
91 type Data = T::Data;
92 type Error = T::Error;
93
94 fn poll_frame(
95 mut self: Pin<&mut Self>,
96 cx: &mut Context<'_>,
97 ) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> {
98 Pin::new(&mut **self).poll_frame(cx)
99 }
100
101 fn is_end_stream(&self) -> bool {
102 Pin::new(&**self).is_end_stream()
103 }
104
105 fn size_hint(&self) -> SizeHint {
106 Pin::new(&**self).size_hint()
107 }
108}
109
110impl<P> Body for Pin<P>
111where
112 P: Unpin + ops::DerefMut,
113 P::Target: Body,
114{
115 type Data = <<P as ops::Deref>::Target as Body>::Data;
116 type Error = <<P as ops::Deref>::Target as Body>::Error;
117
118 fn poll_frame(
119 self: Pin<&mut Self>,
120 cx: &mut Context<'_>,
121 ) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> {
122 Pin::get_mut(self).as_mut().poll_frame(cx)
123 }
124
125 fn is_end_stream(&self) -> bool {
126 self.as_ref().is_end_stream()
127 }
128
129 fn size_hint(&self) -> SizeHint {
130 self.as_ref().size_hint()
131 }
132}
133
134impl<T: Body + Unpin + ?Sized> Body for Box<T> {
135 type Data = T::Data;
136 type Error = T::Error;
137
138 fn poll_frame(
139 mut self: Pin<&mut Self>,
140 cx: &mut Context<'_>,
141 ) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> {
142 Pin::new(&mut **self).poll_frame(cx)
143 }
144
145 fn is_end_stream(&self) -> bool {
146 self.as_ref().is_end_stream()
147 }
148
149 fn size_hint(&self) -> SizeHint {
150 self.as_ref().size_hint()
151 }
152}
153
154impl<B: Body> Body for http::Request<B> {
155 type Data = B::Data;
156 type Error = B::Error;
157
158 fn poll_frame(
159 self: Pin<&mut Self>,
160 cx: &mut Context<'_>,
161 ) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> {
162 unsafe {
165 self.map_unchecked_mut(http::Request::body_mut)
166 .poll_frame(cx)
167 }
168 }
169
170 fn is_end_stream(&self) -> bool {
171 self.body().is_end_stream()
172 }
173
174 fn size_hint(&self) -> SizeHint {
175 self.body().size_hint()
176 }
177}
178
179impl<B: Body> Body for http::Response<B> {
180 type Data = B::Data;
181 type Error = B::Error;
182
183 fn poll_frame(
184 self: Pin<&mut Self>,
185 cx: &mut Context<'_>,
186 ) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> {
187 unsafe {
190 self.map_unchecked_mut(http::Response::body_mut)
191 .poll_frame(cx)
192 }
193 }
194
195 fn is_end_stream(&self) -> bool {
196 self.body().is_end_stream()
197 }
198
199 fn size_hint(&self) -> SizeHint {
200 self.body().size_hint()
201 }
202}
203
204impl Body for String {
205 type Data = Bytes;
206 type Error = Infallible;
207
208 fn poll_frame(
209 mut self: Pin<&mut Self>,
210 _cx: &mut Context<'_>,
211 ) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> {
212 if !self.is_empty() {
213 let s = std::mem::take(&mut *self);
214 Poll::Ready(Some(Ok(Frame::data(s.into_bytes().into()))))
215 } else {
216 Poll::Ready(None)
217 }
218 }
219
220 fn is_end_stream(&self) -> bool {
221 self.is_empty()
222 }
223
224 fn size_hint(&self) -> SizeHint {
225 SizeHint::with_exact(self.len() as u64)
226 }
227}
228
229#[cfg(test)]
230fn _assert_bounds() {
231 fn can_be_trait_object(_: &dyn Body<Data = std::io::Cursor<Vec<u8>>, Error = std::io::Error>) {}
232}