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(
48 self: Pin<&mut Self>,
49 cx: &mut Context<'_>,
50 ) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>>;
51
52 fn is_end_stream(&self) -> bool {
59 false
60 }
61
62 fn size_hint(&self) -> SizeHint {
67 SizeHint::default()
68 }
69}
70
71impl<T: Body + Unpin + ?Sized> Body for &mut T {
72 type Data = T::Data;
73 type Error = T::Error;
74
75 fn poll_frame(
76 mut self: Pin<&mut Self>,
77 cx: &mut Context<'_>,
78 ) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> {
79 Pin::new(&mut **self).poll_frame(cx)
80 }
81
82 fn is_end_stream(&self) -> bool {
83 Pin::new(&**self).is_end_stream()
84 }
85
86 fn size_hint(&self) -> SizeHint {
87 Pin::new(&**self).size_hint()
88 }
89}
90
91impl<P> Body for Pin<P>
92where
93 P: Unpin + ops::DerefMut,
94 P::Target: Body,
95{
96 type Data = <<P as ops::Deref>::Target as Body>::Data;
97 type Error = <<P as ops::Deref>::Target as Body>::Error;
98
99 fn poll_frame(
100 self: Pin<&mut Self>,
101 cx: &mut Context<'_>,
102 ) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> {
103 Pin::get_mut(self).as_mut().poll_frame(cx)
104 }
105
106 fn is_end_stream(&self) -> bool {
107 self.as_ref().is_end_stream()
108 }
109
110 fn size_hint(&self) -> SizeHint {
111 self.as_ref().size_hint()
112 }
113}
114
115impl<T: Body + Unpin + ?Sized> Body for Box<T> {
116 type Data = T::Data;
117 type Error = T::Error;
118
119 fn poll_frame(
120 mut self: Pin<&mut Self>,
121 cx: &mut Context<'_>,
122 ) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> {
123 Pin::new(&mut **self).poll_frame(cx)
124 }
125
126 fn is_end_stream(&self) -> bool {
127 self.as_ref().is_end_stream()
128 }
129
130 fn size_hint(&self) -> SizeHint {
131 self.as_ref().size_hint()
132 }
133}
134
135impl<B: Body> Body for http::Request<B> {
136 type Data = B::Data;
137 type Error = B::Error;
138
139 fn poll_frame(
140 self: Pin<&mut Self>,
141 cx: &mut Context<'_>,
142 ) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> {
143 unsafe {
146 self.map_unchecked_mut(http::Request::body_mut)
147 .poll_frame(cx)
148 }
149 }
150
151 fn is_end_stream(&self) -> bool {
152 self.body().is_end_stream()
153 }
154
155 fn size_hint(&self) -> SizeHint {
156 self.body().size_hint()
157 }
158}
159
160impl<B: Body> Body for http::Response<B> {
161 type Data = B::Data;
162 type Error = B::Error;
163
164 fn poll_frame(
165 self: Pin<&mut Self>,
166 cx: &mut Context<'_>,
167 ) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> {
168 unsafe {
171 self.map_unchecked_mut(http::Response::body_mut)
172 .poll_frame(cx)
173 }
174 }
175
176 fn is_end_stream(&self) -> bool {
177 self.body().is_end_stream()
178 }
179
180 fn size_hint(&self) -> SizeHint {
181 self.body().size_hint()
182 }
183}
184
185impl Body for String {
186 type Data = Bytes;
187 type Error = Infallible;
188
189 fn poll_frame(
190 mut self: Pin<&mut Self>,
191 _cx: &mut Context<'_>,
192 ) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> {
193 if !self.is_empty() {
194 let s = std::mem::take(&mut *self);
195 Poll::Ready(Some(Ok(Frame::data(s.into_bytes().into()))))
196 } else {
197 Poll::Ready(None)
198 }
199 }
200
201 fn is_end_stream(&self) -> bool {
202 self.is_empty()
203 }
204
205 fn size_hint(&self) -> SizeHint {
206 SizeHint::with_exact(self.len() as u64)
207 }
208}
209
210#[cfg(test)]
211fn _assert_bounds() {
212 fn can_be_trait_object(_: &dyn Body<Data = std::io::Cursor<Vec<u8>>, Error = std::io::Error>) {}
213}