keep BoxBody::new

This commit is contained in:
Rob Ede 2021-12-17 00:08:28 +00:00
parent 820bb42f97
commit 88a1999c06
No known key found for this signature in database
GPG Key ID: 97C636207D3EF933
3 changed files with 13 additions and 15 deletions

View File

@ -28,8 +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 method on `MessageBody` trait, `boxed`, for optimisations on boxing body type. [#2520] * New `boxed` method on `MessageBody` trait for wrapping body type. [#2520]
* `BoxBody::new_raw`, which is less performant than `BoxBody::new` but is necessary for the default implmentation of `MessageBody::boxed`. [#2520]
### Changed ### Changed
* Rename `body::BoxBody::{from_body => new}`. [#2468] * Rename `body::BoxBody::{from_body => new}`. [#2468]

View File

@ -15,15 +15,11 @@ pub struct BoxBody(Pin<Box<dyn MessageBody<Error = Box<dyn StdError>>>>);
impl BoxBody { impl BoxBody {
/// Same as `MessageBody::boxed`. /// 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<B>(body: B) -> Self pub fn new<B>(body: B) -> Self
where
B: MessageBody + 'static,
{
body.boxed()
}
/// Boxes a `MessageBody` and any errors it generates.
pub fn new_raw<B>(body: B) -> Self
where where
B: MessageBody + 'static, B: MessageBody + 'static,
{ {
@ -32,6 +28,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]
pub fn as_pin_mut(&mut self) -> Pin<&mut (dyn MessageBody<Error = Box<dyn StdError>>)> { pub fn as_pin_mut(&mut self) -> Pin<&mut (dyn MessageBody<Error = Box<dyn StdError>>)> {
self.0.as_mut() self.0.as_mut()
} }
@ -46,10 +43,12 @@ impl fmt::Debug for BoxBody {
impl MessageBody for BoxBody { impl MessageBody for BoxBody {
type Error = Error; type Error = Error;
#[inline]
fn size(&self) -> BodySize { fn size(&self) -> BodySize {
self.0.size() self.0.size()
} }
#[inline]
fn poll_next( fn poll_next(
mut self: Pin<&mut Self>, mut self: Pin<&mut Self>,
cx: &mut Context<'_>, cx: &mut Context<'_>,
@ -60,10 +59,12 @@ impl MessageBody for BoxBody {
.map_err(|err| Error::new_body().with_cause(err)) .map_err(|err| Error::new_body().with_cause(err))
} }
#[inline]
fn is_complete_body(&self) -> bool { fn is_complete_body(&self) -> bool {
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()
} }

View File

@ -79,14 +79,12 @@ pub trait MessageBody {
} }
/// Converts this body into `BoxBody`. /// Converts this body into `BoxBody`.
/// #[inline]
/// Implementation shouldn't call `BoxBody::new` on `self` as it would cause infinite
/// recursion.
fn boxed(self) -> BoxBody fn boxed(self) -> BoxBody
where where
Self: Sized + 'static, 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()); 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));
} }