From 0d0196120a0c66d142a901260b28661050a9ce09 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Tue, 23 Nov 2021 18:02:00 +0000 Subject: [PATCH] move boxbody to own mod --- actix-http/src/body/body.rs | 75 ++++----------------------------- actix-http/src/body/boxed.rs | 81 ++++++++++++++++++++++++++++++++++++ actix-http/src/body/mod.rs | 2 + src/error/macros.rs | 2 +- 4 files changed, 92 insertions(+), 68 deletions(-) create mode 100644 actix-http/src/body/boxed.rs diff --git a/actix-http/src/body/body.rs b/actix-http/src/body/body.rs index 50230c2eb..1a709f19e 100644 --- a/actix-http/src/body/body.rs +++ b/actix-http/src/body/body.rs @@ -10,10 +10,9 @@ use bytes::{Bytes, BytesMut}; use futures_core::Stream; use pin_project::pin_project; +use super::{BodySize, BodyStream, BoxBody, MessageBody, SizedStream}; use crate::error::Error; -use super::{BodySize, BodyStream, MessageBody, MessageBodyMapErr, SizedStream}; - /// (Deprecated) Represents various types of HTTP message body. #[deprecated(since = "4.0.0", note = "Renamed to `AnyBody`.")] pub type Body = AnyBody; @@ -66,16 +65,18 @@ impl AnyBody { } } +impl AnyBody { + /// Create body from generic message body. + pub fn new(body: B) -> Self { + Self::Body(body) + } +} + impl AnyBody where B: MessageBody + 'static, B::Error: Into>, { - /// Create body from generic message body. - pub fn new(body: B) -> Self { - Self::Body(body) - } - pub fn into_boxed(self) -> AnyBody { match self { Self::None => AnyBody::None, @@ -238,52 +239,6 @@ where } } -/// A boxed message body with boxed errors. -pub struct BoxBody(Pin>>>); - -impl BoxBody { - /// Boxes a `MessageBody` and any errors it generates. - pub fn new(body: B) -> Self - where - B: MessageBody + 'static, - B::Error: Into>, - { - 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>)> { - 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>> { - self.0 - .as_mut() - .poll_next(cx) - .map_err(|err| Error::new_body().with_cause(err)) - } -} - #[cfg(test)] mod tests { use std::marker::PhantomPinned; @@ -291,7 +246,6 @@ mod tests { use static_assertions::{assert_impl_all, assert_not_impl_all}; use super::*; - use crate::body::to_bytes; struct PinType(PhantomPinned); @@ -314,21 +268,8 @@ mod tests { assert_impl_all!(AnyBody>: MessageBody, fmt::Debug, Send, Sync, Unpin); assert_impl_all!(AnyBody: MessageBody, fmt::Debug, Send, Sync, Unpin); assert_impl_all!(AnyBody: MessageBody, fmt::Debug, Unpin); - assert_impl_all!(BoxBody: MessageBody, fmt::Debug, Unpin); assert_impl_all!(AnyBody: MessageBody); assert_not_impl_all!(AnyBody: Send, Sync, Unpin); - assert_not_impl_all!(BoxBody: Send, Sync, Unpin); assert_not_impl_all!(AnyBody: 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]), - ); - } } diff --git a/actix-http/src/body/boxed.rs b/actix-http/src/body/boxed.rs new file mode 100644 index 000000000..75a9e6b7a --- /dev/null +++ b/actix-http/src/body/boxed.rs @@ -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>>>); + +impl BoxBody { + /// Boxes a `MessageBody` and any errors it generates. + pub fn new(body: B) -> Self + where + B: MessageBody + 'static, + B::Error: Into>, + { + 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>)> { + 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>> { + 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]), + ); + } +} diff --git a/actix-http/src/body/mod.rs b/actix-http/src/body/mod.rs index df6c6b08a..c4caad5e0 100644 --- a/actix-http/src/body/mod.rs +++ b/actix-http/src/body/mod.rs @@ -10,6 +10,7 @@ use futures_core::ready; #[allow(clippy::module_inception)] mod body; mod body_stream; +mod boxed; mod message_body; mod size; mod sized_stream; @@ -17,6 +18,7 @@ mod sized_stream; #[allow(deprecated)] pub use self::body::{AnyBody, Body, BoxBody}; pub use self::body_stream::BodyStream; +pub use self::boxed::BoxBody; pub use self::message_body::MessageBody; pub(crate) use self::message_body::MessageBodyMapErr; pub use self::size::BodySize; diff --git a/src/error/macros.rs b/src/error/macros.rs index 38650c5e8..78b1ed9f6 100644 --- a/src/error/macros.rs +++ b/src/error/macros.rs @@ -97,7 +97,7 @@ mod tests { let resp_body: &mut dyn MB = &mut body; let body = resp_body.downcast_ref::().unwrap(); assert_eq!(body, "hello cast"); - let body = &mut resp_body.downcast_mut::().unwrap(); + let body = resp_body.downcast_mut::().unwrap(); body.push('!'); let body = resp_body.downcast_ref::().unwrap(); assert_eq!(body, "hello cast!");