1 | use crate::BodyExt as _; |
2 | |
3 | use bytes::Buf; |
4 | use http_body::{Body, Frame, SizeHint}; |
5 | use std::{ |
6 | fmt, |
7 | pin::Pin, |
8 | task::{Context, Poll}, |
9 | }; |
10 | |
11 | /// A boxed [`Body`] trait object. |
12 | pub 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. |
17 | pub struct UnsyncBoxBody<D, E> { |
18 | inner: Pin<Box<dyn Body<Data = D, Error = E> + Send + 'static>>, |
19 | } |
20 | |
21 | impl<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 | |
34 | impl<D, E> fmt::Debug for BoxBody<D, E> { |
35 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
36 | f.debug_struct(name:"BoxBody" ).finish() |
37 | } |
38 | } |
39 | |
40 | impl<D, E> Body for BoxBody<D, E> |
41 | where |
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 | |
63 | impl<D, E> Default for BoxBody<D, E> |
64 | where |
65 | D: Buf + 'static, |
66 | { |
67 | fn default() -> Self { |
68 | BoxBody::new(body:crate::Empty::new().map_err(|err: Infallible| match err {})) |
69 | } |
70 | } |
71 | |
72 | // === UnsyncBoxBody === |
73 | impl<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 | |
86 | impl<D, E> fmt::Debug for UnsyncBoxBody<D, E> { |
87 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
88 | f.debug_struct(name:"UnsyncBoxBody" ).finish() |
89 | } |
90 | } |
91 | |
92 | impl<D, E> Body for UnsyncBoxBody<D, E> |
93 | where |
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 | |
115 | impl<D, E> Default for UnsyncBoxBody<D, E> |
116 | where |
117 | D: Buf + 'static, |
118 | { |
119 | fn default() -> Self { |
120 | UnsyncBoxBody::new(body:crate::Empty::new().map_err(|err: Infallible| match err {})) |
121 | } |
122 | } |
123 | |