mirror of
https://github.com/fafhrd91/actix-web
synced 2024-11-27 17:52:56 +01:00
MessageBody::boxed (#2520)
Co-authored-by: Rob Ede <robjtede@icloud.com>
This commit is contained in:
parent
44b7302845
commit
3c0d059d92
@ -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
|
||||||
|
@ -14,7 +14,11 @@ use crate::Error;
|
|||||||
pub struct BoxBody(Pin<Box<dyn MessageBody<Error = Box<dyn StdError>>>>);
|
pub struct BoxBody(Pin<Box<dyn MessageBody<Error = Box<dyn StdError>>>>);
|
||||||
|
|
||||||
impl BoxBody {
|
impl BoxBody {
|
||||||
/// Boxes a `MessageBody` and any errors it generates.
|
/// 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
|
where
|
||||||
B: MessageBody + 'static,
|
B: MessageBody + 'static,
|
||||||
@ -24,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()
|
||||||
}
|
}
|
||||||
@ -38,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<'_>,
|
||||||
@ -52,13 +59,20 @@ 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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn boxed(self) -> BoxBody {
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -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)]
|
||||||
|
@ -12,7 +12,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
|
||||||
@ -77,6 +77,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 {
|
||||||
@ -656,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));
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
|
@ -45,9 +45,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.
|
||||||
|
@ -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
|
||||||
|
@ -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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user