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}