Merge branch 'master' into msgb-debug

This commit is contained in:
Rob Ede 2021-12-17 00:44:27 +00:00 committed by GitHub
commit 54a7e23131
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 35 additions and 10 deletions

View File

@ -28,6 +28,7 @@
* `Request::take_req_data()`. [#2487] * `Request::take_req_data()`. [#2487]
* `impl Clone` for `RequestHead`. [#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 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 `boxed` method on `MessageBody` trait for wrapping body type. [#2520]
### Changed ### Changed
* Rename `body::BoxBody::{from_body => new}`. [#2468] * Rename `body::BoxBody::{from_body => new}`. [#2468]
@ -56,6 +57,7 @@
[#2488]: https://github.com/actix/actix-web/pull/2488 [#2488]: https://github.com/actix/actix-web/pull/2488
[#2491]: https://github.com/actix/actix-web/pull/2491 [#2491]: https://github.com/actix/actix-web/pull/2491
[#2497]: https://github.com/actix/actix-web/pull/2497 [#2497]: https://github.com/actix/actix-web/pull/2497
[#2520]: https://github.com/actix/actix-web/pull/2520
## 3.0.0-beta.14 - 2021-11-30 ## 3.0.0-beta.14 - 2021-11-30

View File

@ -13,6 +13,9 @@ pub struct BoxBody(Pin<Box<dyn MessageBody<Error = Box<dyn fmt::Debug>>>>);
impl BoxBody { impl BoxBody {
/// Boxes a `MessageBody` and any errors it generates. /// Boxes a `MessageBody` and any errors it generates.
///
/// If the body type to wrap is unknown or generic it is better to use [`MessageBody::boxed`] to
/// avoid double boxing.
#[inline] #[inline]
pub fn new<B>(body: B) -> Self pub fn new<B>(body: B) -> Self
where where
@ -28,7 +31,7 @@ impl BoxBody {
/// Returns a mutable pinned reference to the inner message body type. /// Returns a mutable pinned reference to the inner message body type.
#[inline] #[inline]
pub fn as_pin_mut(&mut self) -> Pin<&mut (dyn MessageBody<Error = Box<dyn fmt::Debug>>)> { pub fn as_pin_mut(&mut self) -> Pin<&mut (dyn MessageBody<Error = Box<dyn StdError>>)> {
self.0.as_mut() self.0.as_mut()
} }
} }
@ -60,9 +63,15 @@ impl MessageBody for BoxBody {
self.0.is_complete_body() self.0.is_complete_body()
} }
#[inline]
fn take_complete_body(&mut self) -> Bytes { fn take_complete_body(&mut self) -> Bytes {
self.0.take_complete_body() self.0.take_complete_body()
} }
#[inline]
fn boxed(self) -> BoxBody {
self
}
} }
#[cfg(test)] #[cfg(test)]

View File

@ -88,6 +88,14 @@ where
EitherBody::Right { body } => body.take_complete_body(), EitherBody::Right { body } => body.take_complete_body(),
} }
} }
#[inline]
fn boxed(self) -> BoxBody {
match self {
EitherBody::Left { body } => body.boxed(),
EitherBody::Right { body } => body.boxed(),
}
}
} }
#[cfg(test)] #[cfg(test)]

View File

@ -11,7 +11,7 @@ use bytes::{Bytes, BytesMut};
use futures_core::ready; use futures_core::ready;
use pin_project_lite::pin_project; use pin_project_lite::pin_project;
use super::BodySize; use super::{BodySize, BoxBody};
/// An interface types that can converted to bytes and used as response bodies. /// An interface types that can converted to bytes and used as response bodies.
// TODO: examples // TODO: examples
@ -78,6 +78,15 @@ pub trait MessageBody {
std::any::type_name::<Self>() std::any::type_name::<Self>()
); );
} }
/// Converts this body into `BoxBody`.
#[inline]
fn boxed(self) -> BoxBody
where
Self: Sized + 'static,
{
BoxBody::new(self)
}
} }
mod foreign_impls { mod foreign_impls {
@ -657,7 +666,7 @@ mod tests {
assert_eq!(body.take_complete_body(), b"test".as_ref()); assert_eq!(body.take_complete_body(), b"test".as_ref());
// subsequent poll_next returns None // 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); let mut cx = Context::from_waker(&waker);
assert!(Pin::new(&mut body).poll_next(&mut cx).map_err(drop) == Poll::Ready(None)); assert!(Pin::new(&mut body).poll_next(&mut cx).map_err(drop) == Poll::Ready(None));
} }

View File

@ -194,7 +194,7 @@ impl<B> Response<B> {
where where
B: MessageBody + 'static, B: MessageBody + 'static,
{ {
self.map_body(|_, body| BoxBody::new(body)) self.map_body(|_, body| body.boxed())
} }
/// Returns body, consuming this response. /// Returns body, consuming this response.

View File

@ -43,9 +43,7 @@ impl AnyBody {
where where
B: MessageBody + 'static, B: MessageBody + 'static,
{ {
Self::Body { Self::Body { body: body.boxed() }
body: BoxBody::new(body),
}
} }
/// Constructs new `AnyBody` instance from a slice of bytes by copying it. /// Constructs new `AnyBody` instance from a slice of bytes by copying it.

View File

@ -244,8 +244,7 @@ impl<B> HttpResponse<B> {
where where
B: MessageBody + 'static, B: MessageBody + 'static,
{ {
// TODO: avoid double boxing with down-casting, if it improves perf self.map_body(|_, body| body.boxed())
self.map_body(|_, body| BoxBody::new(body))
} }
/// Extract response body /// Extract response body

View File

@ -451,7 +451,7 @@ impl<B> ServiceResponse<B> {
where where
B: MessageBody + 'static, B: MessageBody + 'static,
{ {
self.map_body(|_, body| BoxBody::new(body)) self.map_body(|_, body| body.boxed())
} }
} }