1 | use crate::Body; |
2 | use bytes::Buf; |
3 | use std::{ |
4 | fmt, |
5 | pin::Pin, |
6 | task::{Context, Poll}, |
7 | }; |
8 | |
9 | /// A boxed [`Body`] trait object. |
10 | pub 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. |
15 | pub struct UnsyncBoxBody<D, E> { |
16 | inner: Pin<Box<dyn Body<Data = D, Error = E> + Send + 'static>>, |
17 | } |
18 | |
19 | impl<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 | |
32 | impl<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 | |
38 | impl<D, E> Body for BoxBody<D, E> |
39 | where |
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 | |
68 | impl<D, E> Default for BoxBody<D, E> |
69 | where |
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 === |
78 | impl<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 | |
91 | impl<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 | |
97 | impl<D, E> Body for UnsyncBoxBody<D, E> |
98 | where |
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 | |
127 | impl<D, E> Default for UnsyncBoxBody<D, E> |
128 | where |
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 | |