Skip to content

Commit cab4139

Browse files
authored
Add UnsyncBoxBody combinator (#50)
1 parent 896bff1 commit cab4139

File tree

3 files changed

+78
-2
lines changed

3 files changed

+78
-2
lines changed

src/combinators/box_body.rs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ pub struct BoxBody<D, E> {
1111
inner: Pin<Box<dyn Body<Data = D, Error = E> + Send + Sync + 'static>>,
1212
}
1313

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+
1419
impl<D, E> BoxBody<D, E> {
1520
/// Create a new `BoxBody`.
1621
pub fn new<B>(body: B) -> Self
@@ -68,3 +73,62 @@ where
6873
BoxBody::new(crate::Empty::new().map_err(|err| match err {}))
6974
}
7075
}
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("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(crate::Empty::new().map_err(|err| match err {}))
133+
}
134+
}

src/combinators/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,8 @@ mod box_body;
44
mod map_data;
55
mod map_err;
66

7-
pub use self::{box_body::BoxBody, map_data::MapData, map_err::MapErr};
7+
pub use self::{
8+
box_body::{BoxBody, UnsyncBoxBody},
9+
map_data::MapData,
10+
map_err::MapErr,
11+
};

src/lib.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ pub use self::full::Full;
2525
pub use self::next::{Data, Trailers};
2626
pub use self::size_hint::SizeHint;
2727

28-
use self::combinators::{BoxBody, MapData, MapErr};
28+
use self::combinators::{BoxBody, MapData, MapErr, UnsyncBoxBody};
2929
use bytes::Buf;
3030
use http::HeaderMap;
3131
use std::ops;
@@ -122,6 +122,14 @@ pub trait Body {
122122
{
123123
BoxBody::new(self)
124124
}
125+
126+
/// Turn this body into a boxed trait object that is !Sync.
127+
fn boxed_unsync(self) -> UnsyncBoxBody<Self::Data, Self::Error>
128+
where
129+
Self: Sized + Send + 'static,
130+
{
131+
UnsyncBoxBody::new(self)
132+
}
125133
}
126134

127135
impl<T: Body + Unpin + ?Sized> Body for &mut T {

0 commit comments

Comments
 (0)