diff --git a/actix-http/CHANGES.md b/actix-http/CHANGES.md index d0a492ffd..598ef9c0e 100644 --- a/actix-http/CHANGES.md +++ b/actix-http/CHANGES.md @@ -28,8 +28,7 @@ * `Request::take_req_data()`. [#2487] * `impl Clone` for `RequestHead`. [#2487] * New methods on `MessageBody` trait, `is_complete_body` and `take_complete_body`, both with default implementations, for optimisations on body types that are done in exactly one poll/chunk. [#2497] -* New method on `MessageBody` trait, `boxed`, for optimisations on boxing body type. [#2520] -* `BoxBody::new_raw`, which is less performant than `BoxBody::new` but is necessary for the default implmentation of `MessageBody::boxed`. [#2520] +* New `boxed` method on `MessageBody` trait for wrapping body type. [#2520] ### Changed * Rename `body::BoxBody::{from_body => new}`. [#2468] diff --git a/actix-http/src/body/boxed.rs b/actix-http/src/body/boxed.rs index 734df8404..7581bec88 100644 --- a/actix-http/src/body/boxed.rs +++ b/actix-http/src/body/boxed.rs @@ -15,15 +15,11 @@ pub struct BoxBody(Pin>>>); impl BoxBody { /// Same as `MessageBody::boxed`. + /// + /// If the body type to wrap is unknown or generic it is better to use [`MessageBody::boxed`] to + /// avoid double boxing. + #[inline] pub fn new(body: B) -> Self - where - B: MessageBody + 'static, - { - body.boxed() - } - - /// Boxes a `MessageBody` and any errors it generates. - pub fn new_raw(body: B) -> Self where B: MessageBody + 'static, { @@ -32,6 +28,7 @@ impl BoxBody { } /// Returns a mutable pinned reference to the inner message body type. + #[inline] pub fn as_pin_mut(&mut self) -> Pin<&mut (dyn MessageBody>)> { self.0.as_mut() } @@ -46,10 +43,12 @@ impl fmt::Debug for BoxBody { impl MessageBody for BoxBody { type Error = Error; + #[inline] fn size(&self) -> BodySize { self.0.size() } + #[inline] fn poll_next( mut self: Pin<&mut Self>, cx: &mut Context<'_>, @@ -60,10 +59,12 @@ impl MessageBody for BoxBody { .map_err(|err| Error::new_body().with_cause(err)) } + #[inline] fn is_complete_body(&self) -> bool { self.0.is_complete_body() } + #[inline] fn take_complete_body(&mut self) -> Bytes { self.0.take_complete_body() } diff --git a/actix-http/src/body/message_body.rs b/actix-http/src/body/message_body.rs index ca8a3b2c3..075ae7220 100644 --- a/actix-http/src/body/message_body.rs +++ b/actix-http/src/body/message_body.rs @@ -79,14 +79,12 @@ pub trait MessageBody { } /// Converts this body into `BoxBody`. - /// - /// Implementation shouldn't call `BoxBody::new` on `self` as it would cause infinite - /// recursion. + #[inline] fn boxed(self) -> BoxBody where Self: Sized + 'static, { - BoxBody::new_raw(self) + BoxBody::new(self) } } @@ -667,7 +665,7 @@ mod tests { assert_eq!(body.take_complete_body(), b"test".as_ref()); // subsequent poll_next returns None - let waker = futures_util::task::noop_waker(); + let waker = futures_task::noop_waker(); let mut cx = Context::from_waker(&waker); assert!(Pin::new(&mut body).poll_next(&mut cx).map_err(drop) == Poll::Ready(None)); }