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