1#![doc(html_root_url = "https://docs.rs/http-body/0.4.4")]
2#![deny(
3 missing_debug_implementations,
4 missing_docs,
5 unreachable_pub,
6 broken_intra_doc_links
7)]
8#![cfg_attr(test, deny(warnings))]
9
10mod empty;
17mod full;
18mod next;
19mod size_hint;
20
21pub mod combinators;
22
23pub use self::empty::Empty;
24pub use self::full::Full;
25pub use self::next::{Data, Trailers};
26pub use self::size_hint::SizeHint;
27
28use self::combinators::{BoxBody, MapData, MapErr, UnsyncBoxBody};
29use bytes::Buf;
30use http::HeaderMap;
31use std::ops;
32use std::pin::Pin;
33use std::task::{Context, Poll};
34
35pub trait Body {
44 type Data: Buf;
46
47 type Error;
49
50 fn poll_data(
52 self: Pin<&mut Self>,
53 cx: &mut Context<'_>,
54 ) -> Poll<Option<Result<Self::Data, Self::Error>>>;
55
56 fn poll_trailers(
60 self: Pin<&mut Self>,
61 cx: &mut Context<'_>,
62 ) -> Poll<Result<Option<HeaderMap>, Self::Error>>;
63
64 fn is_end_stream(&self) -> bool {
72 false
73 }
74
75 fn size_hint(&self) -> SizeHint {
80 SizeHint::default()
81 }
82
83 fn data(&mut self) -> Data<'_, Self>
85 where
86 Self: Unpin + Sized,
87 {
88 Data(self)
89 }
90
91 fn trailers(&mut self) -> Trailers<'_, Self>
93 where
94 Self: Unpin + Sized,
95 {
96 Trailers(self)
97 }
98
99 fn map_data<F, B>(self, f: F) -> MapData<Self, F>
101 where
102 Self: Sized,
103 F: FnMut(Self::Data) -> B,
104 B: Buf,
105 {
106 MapData::new(self, f)
107 }
108
109 fn map_err<F, E>(self, f: F) -> MapErr<Self, F>
111 where
112 Self: Sized,
113 F: FnMut(Self::Error) -> E,
114 {
115 MapErr::new(self, f)
116 }
117
118 fn boxed(self) -> BoxBody<Self::Data, Self::Error>
120 where
121 Self: Sized + Send + Sync + 'static,
122 {
123 BoxBody::new(self)
124 }
125
126 fn boxed_unsync(self) -> UnsyncBoxBody<Self::Data, Self::Error>
128 where
129 Self: Sized + Send + 'static,
130 {
131 UnsyncBoxBody::new(self)
132 }
133}
134
135impl<T: Body + Unpin + ?Sized> Body for &mut T {
136 type Data = T::Data;
137 type Error = T::Error;
138
139 fn poll_data(
140 mut self: Pin<&mut Self>,
141 cx: &mut Context<'_>,
142 ) -> Poll<Option<Result<Self::Data, Self::Error>>> {
143 Pin::new(&mut **self).poll_data(cx)
144 }
145
146 fn poll_trailers(
147 mut self: Pin<&mut Self>,
148 cx: &mut Context<'_>,
149 ) -> Poll<Result<Option<HeaderMap>, Self::Error>> {
150 Pin::new(&mut **self).poll_trailers(cx)
151 }
152
153 fn is_end_stream(&self) -> bool {
154 Pin::new(&**self).is_end_stream()
155 }
156
157 fn size_hint(&self) -> SizeHint {
158 Pin::new(&**self).size_hint()
159 }
160}
161
162impl<P> Body for Pin<P>
163where
164 P: Unpin + ops::DerefMut,
165 P::Target: Body,
166{
167 type Data = <<P as ops::Deref>::Target as Body>::Data;
168 type Error = <<P as ops::Deref>::Target as Body>::Error;
169
170 fn poll_data(
171 self: Pin<&mut Self>,
172 cx: &mut Context<'_>,
173 ) -> Poll<Option<Result<Self::Data, Self::Error>>> {
174 Pin::get_mut(self).as_mut().poll_data(cx)
175 }
176
177 fn poll_trailers(
178 self: Pin<&mut Self>,
179 cx: &mut Context<'_>,
180 ) -> Poll<Result<Option<HeaderMap>, Self::Error>> {
181 Pin::get_mut(self).as_mut().poll_trailers(cx)
182 }
183
184 fn is_end_stream(&self) -> bool {
185 self.as_ref().is_end_stream()
186 }
187
188 fn size_hint(&self) -> SizeHint {
189 self.as_ref().size_hint()
190 }
191}
192
193impl<T: Body + Unpin + ?Sized> Body for Box<T> {
194 type Data = T::Data;
195 type Error = T::Error;
196
197 fn poll_data(
198 mut self: Pin<&mut Self>,
199 cx: &mut Context<'_>,
200 ) -> Poll<Option<Result<Self::Data, Self::Error>>> {
201 Pin::new(&mut **self).poll_data(cx)
202 }
203
204 fn poll_trailers(
205 mut self: Pin<&mut Self>,
206 cx: &mut Context<'_>,
207 ) -> Poll<Result<Option<HeaderMap>, Self::Error>> {
208 Pin::new(&mut **self).poll_trailers(cx)
209 }
210
211 fn is_end_stream(&self) -> bool {
212 self.as_ref().is_end_stream()
213 }
214
215 fn size_hint(&self) -> SizeHint {
216 self.as_ref().size_hint()
217 }
218}
219
220impl<B: Body> Body for http::Request<B> {
221 type Data = B::Data;
222 type Error = B::Error;
223
224 fn poll_data(
225 self: Pin<&mut Self>,
226 cx: &mut Context<'_>,
227 ) -> Poll<Option<Result<Self::Data, Self::Error>>> {
228 unsafe {
229 self.map_unchecked_mut(http::Request::body_mut)
230 .poll_data(cx)
231 }
232 }
233
234 fn poll_trailers(
235 self: Pin<&mut Self>,
236 cx: &mut Context<'_>,
237 ) -> Poll<Result<Option<HeaderMap>, Self::Error>> {
238 unsafe {
239 self.map_unchecked_mut(http::Request::body_mut)
240 .poll_trailers(cx)
241 }
242 }
243
244 fn is_end_stream(&self) -> bool {
245 self.body().is_end_stream()
246 }
247
248 fn size_hint(&self) -> SizeHint {
249 self.body().size_hint()
250 }
251}
252
253impl<B: Body> Body for http::Response<B> {
254 type Data = B::Data;
255 type Error = B::Error;
256
257 fn poll_data(
258 self: Pin<&mut Self>,
259 cx: &mut Context<'_>,
260 ) -> Poll<Option<Result<Self::Data, Self::Error>>> {
261 unsafe {
262 self.map_unchecked_mut(http::Response::body_mut)
263 .poll_data(cx)
264 }
265 }
266
267 fn poll_trailers(
268 self: Pin<&mut Self>,
269 cx: &mut Context<'_>,
270 ) -> Poll<Result<Option<HeaderMap>, Self::Error>> {
271 unsafe {
272 self.map_unchecked_mut(http::Response::body_mut)
273 .poll_trailers(cx)
274 }
275 }
276
277 fn is_end_stream(&self) -> bool {
278 self.body().is_end_stream()
279 }
280
281 fn size_hint(&self) -> SizeHint {
282 self.body().size_hint()
283 }
284}
285
286#[cfg(test)]
287fn _assert_bounds() {
288 fn can_be_trait_object(_: &dyn Body<Data = std::io::Cursor<Vec<u8>>, Error = std::io::Error>) {}
289}