move boxbody to own mod

This commit is contained in:
Rob Ede 2021-11-23 18:02:00 +00:00
parent 25e3867b1d
commit 0d0196120a
No known key found for this signature in database
GPG Key ID: 97C636207D3EF933
4 changed files with 92 additions and 68 deletions

View File

@ -10,10 +10,9 @@ use bytes::{Bytes, BytesMut};
use futures_core::Stream; use futures_core::Stream;
use pin_project::pin_project; use pin_project::pin_project;
use super::{BodySize, BodyStream, BoxBody, MessageBody, SizedStream};
use crate::error::Error; use crate::error::Error;
use super::{BodySize, BodyStream, MessageBody, MessageBodyMapErr, SizedStream};
/// (Deprecated) Represents various types of HTTP message body. /// (Deprecated) Represents various types of HTTP message body.
#[deprecated(since = "4.0.0", note = "Renamed to `AnyBody`.")] #[deprecated(since = "4.0.0", note = "Renamed to `AnyBody`.")]
pub type Body = AnyBody; pub type Body = AnyBody;
@ -66,16 +65,18 @@ impl AnyBody {
} }
} }
impl<B> AnyBody<B> {
/// Create body from generic message body.
pub fn new(body: B) -> Self {
Self::Body(body)
}
}
impl<B> AnyBody<B> impl<B> AnyBody<B>
where where
B: MessageBody + 'static, B: MessageBody + 'static,
B::Error: Into<Box<dyn StdError + 'static>>, B::Error: Into<Box<dyn StdError + 'static>>,
{ {
/// Create body from generic message body.
pub fn new(body: B) -> Self {
Self::Body(body)
}
pub fn into_boxed(self) -> AnyBody { pub fn into_boxed(self) -> AnyBody {
match self { match self {
Self::None => AnyBody::None, Self::None => AnyBody::None,
@ -238,52 +239,6 @@ where
} }
} }
/// A boxed message body with boxed errors.
pub struct BoxBody(Pin<Box<dyn MessageBody<Error = Box<dyn StdError>>>>);
impl BoxBody {
/// Boxes a `MessageBody` and any errors it generates.
pub fn new<B>(body: B) -> Self
where
B: MessageBody + 'static,
B::Error: Into<Box<dyn StdError + 'static>>,
{
let body = MessageBodyMapErr::new(body, Into::into);
Self(Box::pin(body))
}
/// Returns a mutable pinned reference to the inner message body type.
pub fn as_pin_mut(
&mut self,
) -> Pin<&mut (dyn MessageBody<Error = Box<dyn StdError>>)> {
self.0.as_mut()
}
}
impl fmt::Debug for BoxBody {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("BoxAnyBody(dyn MessageBody)")
}
}
impl MessageBody for BoxBody {
type Error = Error;
fn size(&self) -> BodySize {
self.0.size()
}
fn poll_next(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Option<Result<Bytes, Self::Error>>> {
self.0
.as_mut()
.poll_next(cx)
.map_err(|err| Error::new_body().with_cause(err))
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::marker::PhantomPinned; use std::marker::PhantomPinned;
@ -291,7 +246,6 @@ mod tests {
use static_assertions::{assert_impl_all, assert_not_impl_all}; use static_assertions::{assert_impl_all, assert_not_impl_all};
use super::*; use super::*;
use crate::body::to_bytes;
struct PinType(PhantomPinned); struct PinType(PhantomPinned);
@ -314,21 +268,8 @@ mod tests {
assert_impl_all!(AnyBody<AnyBody<()>>: MessageBody, fmt::Debug, Send, Sync, Unpin); assert_impl_all!(AnyBody<AnyBody<()>>: MessageBody, fmt::Debug, Send, Sync, Unpin);
assert_impl_all!(AnyBody<Bytes>: MessageBody, fmt::Debug, Send, Sync, Unpin); assert_impl_all!(AnyBody<Bytes>: MessageBody, fmt::Debug, Send, Sync, Unpin);
assert_impl_all!(AnyBody: MessageBody, fmt::Debug, Unpin); assert_impl_all!(AnyBody: MessageBody, fmt::Debug, Unpin);
assert_impl_all!(BoxBody: MessageBody, fmt::Debug, Unpin);
assert_impl_all!(AnyBody<PinType>: MessageBody); assert_impl_all!(AnyBody<PinType>: MessageBody);
assert_not_impl_all!(AnyBody: Send, Sync, Unpin); assert_not_impl_all!(AnyBody: Send, Sync, Unpin);
assert_not_impl_all!(BoxBody: Send, Sync, Unpin);
assert_not_impl_all!(AnyBody<PinType>: Send, Sync, Unpin); assert_not_impl_all!(AnyBody<PinType>: Send, Sync, Unpin);
#[actix_rt::test]
async fn nested_boxed_body() {
let body = AnyBody::copy_from_slice(&[1, 2, 3]);
let boxed_body = BoxBody::new(BoxBody::new(body));
assert_eq!(
to_bytes(boxed_body).await.unwrap(),
Bytes::from(vec![1, 2, 3]),
);
}
} }

View File

@ -0,0 +1,81 @@
use std::{
error::Error as StdError,
fmt,
pin::Pin,
task::{Context, Poll},
};
use bytes::Bytes;
use super::{BodySize, MessageBody, MessageBodyMapErr};
use crate::Error;
/// A boxed message body with boxed errors.
pub struct BoxBody(Pin<Box<dyn MessageBody<Error = Box<dyn StdError>>>>);
impl BoxBody {
/// Boxes a `MessageBody` and any errors it generates.
pub fn new<B>(body: B) -> Self
where
B: MessageBody + 'static,
B::Error: Into<Box<dyn StdError + 'static>>,
{
let body = MessageBodyMapErr::new(body, Into::into);
Self(Box::pin(body))
}
/// Returns a mutable pinned reference to the inner message body type.
pub fn as_pin_mut(
&mut self,
) -> Pin<&mut (dyn MessageBody<Error = Box<dyn StdError>>)> {
self.0.as_mut()
}
}
impl fmt::Debug for BoxBody {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("BoxAnyBody(dyn MessageBody)")
}
}
impl MessageBody for BoxBody {
type Error = Error;
fn size(&self) -> BodySize {
self.0.size()
}
fn poll_next(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Option<Result<Bytes, Self::Error>>> {
self.0
.as_mut()
.poll_next(cx)
.map_err(|err| Error::new_body().with_cause(err))
}
}
#[cfg(test)]
mod tests {
use static_assertions::{assert_impl_all, assert_not_impl_all};
use super::*;
use crate::body::to_bytes;
assert_impl_all!(BoxBody: MessageBody, fmt::Debug, Unpin);
assert_not_impl_all!(BoxBody: Send, Sync, Unpin);
#[actix_rt::test]
async fn nested_boxed_body() {
let body = Bytes::from(&[1, 2, 3]);
let boxed_body = BoxBody::new(BoxBody::new(body));
assert_eq!(
to_bytes(boxed_body).await.unwrap(),
Bytes::from(vec![1, 2, 3]),
);
}
}

View File

@ -10,6 +10,7 @@ use futures_core::ready;
#[allow(clippy::module_inception)] #[allow(clippy::module_inception)]
mod body; mod body;
mod body_stream; mod body_stream;
mod boxed;
mod message_body; mod message_body;
mod size; mod size;
mod sized_stream; mod sized_stream;
@ -17,6 +18,7 @@ mod sized_stream;
#[allow(deprecated)] #[allow(deprecated)]
pub use self::body::{AnyBody, Body, BoxBody}; pub use self::body::{AnyBody, Body, BoxBody};
pub use self::body_stream::BodyStream; pub use self::body_stream::BodyStream;
pub use self::boxed::BoxBody;
pub use self::message_body::MessageBody; pub use self::message_body::MessageBody;
pub(crate) use self::message_body::MessageBodyMapErr; pub(crate) use self::message_body::MessageBodyMapErr;
pub use self::size::BodySize; pub use self::size::BodySize;

View File

@ -97,7 +97,7 @@ mod tests {
let resp_body: &mut dyn MB = &mut body; let resp_body: &mut dyn MB = &mut body;
let body = resp_body.downcast_ref::<String>().unwrap(); let body = resp_body.downcast_ref::<String>().unwrap();
assert_eq!(body, "hello cast"); assert_eq!(body, "hello cast");
let body = &mut resp_body.downcast_mut::<String>().unwrap(); let body = resp_body.downcast_mut::<String>().unwrap();
body.push('!'); body.push('!');
let body = resp_body.downcast_ref::<String>().unwrap(); let body = resp_body.downcast_ref::<String>().unwrap();
assert_eq!(body, "hello cast!"); assert_eq!(body, "hello cast!");