1use core::{
2 convert::Infallible,
3 marker::PhantomData,
4 pin::Pin,
5 task::{Context, Poll},
6};
7
8use bytes::Buf;
9use futures_core::stream::Stream;
10use http::header::HeaderMap;
11use pin_project_lite::pin_project;
12
13use super::{body::Body, frame::Frame, size_hint::SizeHint};
14
15pin_project! {
16 #[derive(Clone, Copy, Debug)]
18 pub struct Full<D> {
19 data: Option<D>,
20 }
21}
22
23impl<D> Full<D>
24where
25 D: Buf,
26{
27 #[inline]
29 pub const fn new(data: D) -> Self {
30 Self { data: Some(data) }
31 }
32}
33
34impl<D> Body for Full<D>
35where
36 D: Buf,
37{
38 type Data = D;
39 type Error = Infallible;
40
41 #[inline]
42 fn poll_frame(
43 mut self: Pin<&mut Self>,
44 _: &mut Context<'_>,
45 ) -> Poll<Option<Result<crate::Frame<Self::Data>, Self::Error>>> {
46 Poll::Ready(self.data.take().map(|d| Ok(Frame::Data(d))))
47 }
48
49 #[inline]
50 fn is_end_stream(&self) -> bool {
51 self.data.is_none()
52 }
53
54 #[inline]
55 fn size_hint(&self) -> SizeHint {
56 match self.data {
57 Some(ref data) => SizeHint::exact(data.remaining()),
58 None => SizeHint::None,
59 }
60 }
61}
62
63#[derive(Debug, Default, Clone, Copy)]
64pub struct Empty<D>(PhantomData<fn(D)>);
65
66impl<D> Empty<D> {
67 pub const fn new() -> Self {
68 Self(PhantomData)
69 }
70}
71
72impl<D> Body for Empty<D> {
73 type Data = D;
74 type Error = Infallible;
75
76 #[inline]
77 fn poll_frame(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> {
78 Poll::Ready(None)
79 }
80
81 #[inline]
82 fn is_end_stream(&self) -> bool {
83 true
84 }
85
86 #[inline]
87 fn size_hint(&self) -> SizeHint {
88 SizeHint::None
89 }
90}
91
92pin_project! {
93 pub struct Either<L, R> {
94 #[pin]
95 inner: EitherInner<L, R>
96 }
97}
98
99pin_project! {
100 #[project = EitherProj]
101 enum EitherInner<L, R> {
102 L {
103 #[pin]
104 inner: L
105 },
106 R {
107 #[pin]
108 inner: R
109 }
110 }
111}
112
113impl<L, R> Either<L, R> {
114 #[inline]
115 pub const fn left(inner: L) -> Self {
116 Self {
117 inner: EitherInner::L { inner },
118 }
119 }
120
121 #[inline]
122 pub const fn right(inner: R) -> Self {
123 Self {
124 inner: EitherInner::R { inner },
125 }
126 }
127
128 #[inline]
129 pub fn into_left(self) -> Result<L, Self> {
130 match self.inner {
131 EitherInner::L { inner } => Ok(inner),
132 inner => Err(Self { inner }),
133 }
134 }
135
136 #[inline]
137 pub fn into_right(self) -> Result<R, Self> {
138 match self.inner {
139 EitherInner::R { inner } => Ok(inner),
140 inner => Err(Self { inner }),
141 }
142 }
143}
144
145impl<L> Either<L, L> {
146 #[inline]
147 pub fn into_inner(self) -> L {
148 match self.inner {
149 EitherInner::L { inner } => inner,
150 EitherInner::R { inner } => inner,
151 }
152 }
153}
154
155impl<L, R> Body for Either<L, R>
156where
157 L: Body,
158 R: Body<Data = L::Data>,
159 R::Error: From<L::Error>,
160{
161 type Data = L::Data;
162 type Error = R::Error;
163
164 #[inline]
165 fn poll_frame(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> {
166 match self.project().inner.project() {
167 EitherProj::L { inner } => inner.poll_frame(cx).map(|res| res.map(|res| res.map_err(Into::into))),
168 EitherProj::R { inner } => inner.poll_frame(cx),
169 }
170 }
171
172 #[inline]
173 fn is_end_stream(&self) -> bool {
174 match self.inner {
175 EitherInner::L { ref inner } => inner.is_end_stream(),
176 EitherInner::R { ref inner } => inner.is_end_stream(),
177 }
178 }
179
180 #[inline]
181 fn size_hint(&self) -> SizeHint {
182 match self.inner {
183 EitherInner::L { ref inner } => inner.size_hint(),
184 EitherInner::R { ref inner } => inner.size_hint(),
185 }
186 }
187}
188
189pin_project! {
190 #[derive(Debug)]
196 pub struct StreamBody<T> {
197 #[pin]
198 pub(crate) value: T
199 }
200}
201
202impl<T> StreamBody<T> {
203 pub fn new(value: T) -> Self {
204 Self { value }
205 }
206}
207
208impl<S, D, E> Body for StreamBody<S>
209where
210 S: Stream<Item = Result<Frame<D>, E>>,
211{
212 type Data = D;
213 type Error = E;
214
215 #[inline]
216 fn poll_frame(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> {
217 Stream::poll_next(self.project().value, cx)
218 }
219
220 #[inline]
221 fn is_end_stream(&self) -> bool {
222 false
223 }
224
225 #[inline]
226 fn size_hint(&self) -> SizeHint {
227 match Stream::size_hint(&self.value) {
228 (low, Some(up)) if low == up => SizeHint::exact(low),
229 SizeHint::NO_BODY_HINT => SizeHint::None,
230 _ => SizeHint::Unknown,
231 }
232 }
233}
234
235pin_project! {
236 #[derive(Debug)]
242 pub struct StreamDataBody<T> {
243 #[pin]
244 pub(crate) value: T
245 }
246}
247
248impl<T> StreamDataBody<T> {
249 pub fn new(value: T) -> Self {
250 Self { value }
251 }
252}
253
254impl<S, T, E> Body for StreamDataBody<S>
255where
256 S: Stream<Item = Result<T, E>>,
257{
258 type Data = T;
259 type Error = E;
260
261 #[inline]
262 fn poll_frame(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> {
263 Stream::poll_next(self.project().value, cx).map_ok(Frame::Data)
264 }
265
266 #[inline]
267 fn is_end_stream(&self) -> bool {
268 false
269 }
270
271 #[inline]
272 fn size_hint(&self) -> SizeHint {
273 SizeHint::from_stream_size_hint(self.value.size_hint())
274 }
275}
276
277pin_project! {
278 pub struct Data<B> {
279 #[pin]
280 body: B
281 }
282}
283
284impl<B> Data<B>
285where
286 B: Body,
287{
288 pub fn new(body: B) -> Self {
289 Self { body }
290 }
291}
292
293impl<B> Body for Data<B>
294where
295 B: Body,
296{
297 type Data = B::Data;
298 type Error = B::Error;
299
300 #[inline]
301 fn poll_frame(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> {
302 match self.project().body.poll_frame(cx) {
303 Poll::Ready(Some(Ok(Frame::Trailers(_)))) => Poll::Ready(None),
304 res => res,
305 }
306 }
307
308 #[inline]
309 fn is_end_stream(&self) -> bool {
310 self.body.is_end_stream()
311 }
312
313 #[inline]
314 fn size_hint(&self) -> SizeHint {
315 self.body.size_hint()
316 }
317}
318
319pub struct Trailers<D> {
320 trailers: Option<HeaderMap>,
321 _data: PhantomData<fn(D)>,
322}
323
324impl<D> Trailers<D> {
325 pub fn new(trailers: HeaderMap) -> Self {
326 Self {
327 trailers: Some(trailers),
328 _data: PhantomData,
329 }
330 }
331}
332
333impl<D> Body for Trailers<D> {
334 type Data = D;
335 type Error = Infallible;
336
337 #[inline]
338 fn poll_frame(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> {
339 Poll::Ready(
340 self.get_mut()
341 .trailers
342 .take()
343 .map(|trailers| Ok(Frame::Trailers(trailers))),
344 )
345 }
346
347 #[inline]
348 fn is_end_stream(&self) -> bool {
349 self.trailers.is_none()
350 }
351
352 #[inline]
353 fn size_hint(&self) -> SizeHint {
354 SizeHint::None
355 }
356}