http_body_util/combinators/
box_body.rs

1use crate::BodyExt as _;
2
3use bytes::Buf;
4use http_body::{Body, Frame, SizeHint};
5use std::{
6    fmt,
7    pin::Pin,
8    task::{Context, Poll},
9};
10
11/// A boxed [`Body`] trait object.
12pub struct BoxBody<D, E> {
13    inner: Pin<Box<dyn Body<Data = D, Error = E> + Send + Sync + 'static>>,
14}
15
16/// A boxed [`Body`] trait object that is !Sync.
17pub struct UnsyncBoxBody<D, E> {
18    inner: Pin<Box<dyn Body<Data = D, Error = E> + Send + 'static>>,
19}
20
21impl<D, E> BoxBody<D, E> {
22    /// Create a new `BoxBody`.
23    pub fn new<B>(body: B) -> Self
24    where
25        B: Body<Data = D, Error = E> + Send + Sync + 'static,
26        D: Buf,
27    {
28        Self {
29            inner: Box::pin(body),
30        }
31    }
32}
33
34impl<D, E> fmt::Debug for BoxBody<D, E> {
35    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36        f.debug_struct("BoxBody").finish()
37    }
38}
39
40impl<D, E> Body for BoxBody<D, E>
41where
42    D: Buf,
43{
44    type Data = D;
45    type Error = E;
46
47    fn poll_frame(
48        mut self: Pin<&mut Self>,
49        cx: &mut Context<'_>,
50    ) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> {
51        self.inner.as_mut().poll_frame(cx)
52    }
53
54    fn is_end_stream(&self) -> bool {
55        self.inner.is_end_stream()
56    }
57
58    fn size_hint(&self) -> SizeHint {
59        self.inner.size_hint()
60    }
61}
62
63impl<D, E> Default for BoxBody<D, E>
64where
65    D: Buf + 'static,
66{
67    fn default() -> Self {
68        BoxBody::new(crate::Empty::new().map_err(|err| match err {}))
69    }
70}
71
72// === UnsyncBoxBody ===
73impl<D, E> UnsyncBoxBody<D, E> {
74    /// Create a new `UnsyncBoxBody`.
75    pub fn new<B>(body: B) -> Self
76    where
77        B: Body<Data = D, Error = E> + Send + 'static,
78        D: Buf,
79    {
80        Self {
81            inner: Box::pin(body),
82        }
83    }
84}
85
86impl<D, E> fmt::Debug for UnsyncBoxBody<D, E> {
87    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
88        f.debug_struct("UnsyncBoxBody").finish()
89    }
90}
91
92impl<D, E> Body for UnsyncBoxBody<D, E>
93where
94    D: Buf,
95{
96    type Data = D;
97    type Error = E;
98
99    fn poll_frame(
100        mut self: Pin<&mut Self>,
101        cx: &mut Context<'_>,
102    ) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> {
103        self.inner.as_mut().poll_frame(cx)
104    }
105
106    fn is_end_stream(&self) -> bool {
107        self.inner.is_end_stream()
108    }
109
110    fn size_hint(&self) -> SizeHint {
111        self.inner.size_hint()
112    }
113}
114
115impl<D, E> Default for UnsyncBoxBody<D, E>
116where
117    D: Buf + 'static,
118{
119    fn default() -> Self {
120        UnsyncBoxBody::new(crate::Empty::new().map_err(|err| match err {}))
121    }
122}