mirror of https://github.com/fafhrd91/actix-web
use pin-project-lite on anybody
This commit is contained in:
parent
81d6fb4d65
commit
aec0e46909
|
@ -8,7 +8,7 @@ use std::{
|
||||||
|
|
||||||
use bytes::{Bytes, BytesMut};
|
use bytes::{Bytes, BytesMut};
|
||||||
use futures_core::Stream;
|
use futures_core::Stream;
|
||||||
use pin_project::pin_project;
|
use pin_project_lite::pin_project;
|
||||||
|
|
||||||
use super::{BodySize, BodyStream, BoxBody, MessageBody, SizedStream};
|
use super::{BodySize, BodyStream, BoxBody, MessageBody, SizedStream};
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
|
@ -17,18 +17,20 @@ use crate::error::Error;
|
||||||
#[deprecated(since = "4.0.0", note = "Renamed to `AnyBody`.")]
|
#[deprecated(since = "4.0.0", note = "Renamed to `AnyBody`.")]
|
||||||
pub type Body = AnyBody;
|
pub type Body = AnyBody;
|
||||||
|
|
||||||
/// Represents various types of HTTP message body.
|
pin_project! {
|
||||||
#[pin_project(project = AnyBodyProj)]
|
/// Represents various types of HTTP message body.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum AnyBody<B = BoxBody> {
|
#[project = AnyBodyProj]
|
||||||
/// Empty response. `Content-Length` header is not set.
|
pub enum AnyBody<B = BoxBody> {
|
||||||
None,
|
/// Empty response. `Content-Length` header is not set.
|
||||||
|
None,
|
||||||
|
|
||||||
/// Complete, in-memory response body.
|
/// Complete, in-memory response body.
|
||||||
Bytes(Bytes),
|
Bytes { body: Bytes },
|
||||||
|
|
||||||
/// Generic / Other message body.
|
/// Generic / Other message body.
|
||||||
Body(#[pin] B),
|
Body { #[pin] body: B },
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AnyBody {
|
impl AnyBody {
|
||||||
|
@ -39,7 +41,7 @@ impl AnyBody {
|
||||||
|
|
||||||
/// Constructs a new, 0-length body.
|
/// Constructs a new, 0-length body.
|
||||||
pub fn empty() -> Self {
|
pub fn empty() -> Self {
|
||||||
Self::Bytes(Bytes::new())
|
Self::Bytes { body: Bytes::new() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create boxed body from generic message body.
|
/// Create boxed body from generic message body.
|
||||||
|
@ -48,27 +50,33 @@ impl AnyBody {
|
||||||
B: MessageBody + 'static,
|
B: MessageBody + 'static,
|
||||||
B::Error: Into<Box<dyn StdError + 'static>>,
|
B::Error: Into<Box<dyn StdError + 'static>>,
|
||||||
{
|
{
|
||||||
Self::Body(BoxBody::new(body))
|
Self::Body {
|
||||||
|
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.
|
||||||
///
|
///
|
||||||
/// If your bytes container is owned, it may be cheaper to use a `From` impl.
|
/// If your bytes container is owned, it may be cheaper to use a `From` impl.
|
||||||
pub fn copy_from_slice(s: &[u8]) -> Self {
|
pub fn copy_from_slice(s: &[u8]) -> Self {
|
||||||
Self::Bytes(Bytes::copy_from_slice(s))
|
Self::Bytes {
|
||||||
|
body: Bytes::copy_from_slice(s),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
#[deprecated(since = "4.0.0", note = "Renamed to `copy_from_slice`.")]
|
#[deprecated(since = "4.0.0", note = "Renamed to `copy_from_slice`.")]
|
||||||
pub fn from_slice(s: &[u8]) -> Self {
|
pub fn from_slice(s: &[u8]) -> Self {
|
||||||
Self::Bytes(Bytes::copy_from_slice(s))
|
Self::Bytes {
|
||||||
|
body: Bytes::copy_from_slice(s),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B> AnyBody<B> {
|
impl<B> AnyBody<B> {
|
||||||
/// Create body from generic message body.
|
/// Create body from generic message body.
|
||||||
pub fn new(body: B) -> Self {
|
pub fn new(body: B) -> Self {
|
||||||
Self::Body(body)
|
Self::Body { body }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,8 +88,8 @@ where
|
||||||
pub fn into_boxed(self) -> AnyBody {
|
pub fn into_boxed(self) -> AnyBody {
|
||||||
match self {
|
match self {
|
||||||
Self::None => AnyBody::None,
|
Self::None => AnyBody::None,
|
||||||
Self::Bytes(bytes) => AnyBody::Bytes(bytes),
|
Self::Bytes { body: bytes } => AnyBody::Bytes { body: bytes },
|
||||||
Self::Body(body) => AnyBody::new_boxed(body),
|
Self::Body { body } => AnyBody::new_boxed(body),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,8 +104,8 @@ where
|
||||||
fn size(&self) -> BodySize {
|
fn size(&self) -> BodySize {
|
||||||
match self {
|
match self {
|
||||||
AnyBody::None => BodySize::None,
|
AnyBody::None => BodySize::None,
|
||||||
AnyBody::Bytes(ref bin) => BodySize::Sized(bin.len() as u64),
|
AnyBody::Bytes { ref body } => BodySize::Sized(body.len() as u64),
|
||||||
AnyBody::Body(ref body) => body.size(),
|
AnyBody::Body { ref body } => body.size(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,16 +115,16 @@ where
|
||||||
) -> Poll<Option<Result<Bytes, Self::Error>>> {
|
) -> Poll<Option<Result<Bytes, Self::Error>>> {
|
||||||
match self.project() {
|
match self.project() {
|
||||||
AnyBodyProj::None => Poll::Ready(None),
|
AnyBodyProj::None => Poll::Ready(None),
|
||||||
AnyBodyProj::Bytes(bin) => {
|
AnyBodyProj::Bytes { body } => {
|
||||||
let len = bin.len();
|
let len = body.len();
|
||||||
if len == 0 {
|
if len == 0 {
|
||||||
Poll::Ready(None)
|
Poll::Ready(None)
|
||||||
} else {
|
} else {
|
||||||
Poll::Ready(Some(Ok(mem::take(bin))))
|
Poll::Ready(Some(Ok(mem::take(body))))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AnyBodyProj::Body(body) => body
|
AnyBodyProj::Body { body } => body
|
||||||
.poll_next(cx)
|
.poll_next(cx)
|
||||||
.map_err(|err| Error::new_body().with_cause(err)),
|
.map_err(|err| Error::new_body().with_cause(err)),
|
||||||
}
|
}
|
||||||
|
@ -125,13 +133,13 @@ where
|
||||||
|
|
||||||
impl PartialEq for AnyBody {
|
impl PartialEq for AnyBody {
|
||||||
fn eq(&self, other: &AnyBody) -> bool {
|
fn eq(&self, other: &AnyBody) -> bool {
|
||||||
match *self {
|
match self {
|
||||||
AnyBody::None => matches!(*other, AnyBody::None),
|
AnyBody::None => matches!(*other, AnyBody::None),
|
||||||
AnyBody::Bytes(ref b) => match *other {
|
AnyBody::Bytes { body } => match other {
|
||||||
AnyBody::Bytes(ref b2) => b == b2,
|
AnyBody::Bytes { body: b2 } => body == b2,
|
||||||
_ => false,
|
_ => false,
|
||||||
},
|
},
|
||||||
AnyBody::Body(_) => false,
|
AnyBody::Body { .. } => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -140,39 +148,49 @@ impl<S: fmt::Debug> fmt::Debug for AnyBody<S> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match *self {
|
match *self {
|
||||||
AnyBody::None => write!(f, "AnyBody::None"),
|
AnyBody::None => write!(f, "AnyBody::None"),
|
||||||
AnyBody::Bytes(ref bytes) => write!(f, "AnyBody::Bytes({:?})", bytes),
|
AnyBody::Bytes { ref body } => write!(f, "AnyBody::Bytes({:?})", body),
|
||||||
AnyBody::Body(ref stream) => write!(f, "AnyBody::Message({:?})", stream),
|
AnyBody::Body { ref body } => write!(f, "AnyBody::Message({:?})", body),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B> From<&'static str> for AnyBody<B> {
|
impl<B> From<&'static str> for AnyBody<B> {
|
||||||
fn from(string: &'static str) -> Self {
|
fn from(string: &'static str) -> Self {
|
||||||
Self::Bytes(Bytes::from_static(string.as_ref()))
|
Self::Bytes {
|
||||||
|
body: Bytes::from_static(string.as_ref()),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B> From<&'static [u8]> for AnyBody<B> {
|
impl<B> From<&'static [u8]> for AnyBody<B> {
|
||||||
fn from(bytes: &'static [u8]) -> Self {
|
fn from(bytes: &'static [u8]) -> Self {
|
||||||
Self::Bytes(Bytes::from_static(bytes))
|
Self::Bytes {
|
||||||
|
body: Bytes::from_static(bytes),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B> From<Vec<u8>> for AnyBody<B> {
|
impl<B> From<Vec<u8>> for AnyBody<B> {
|
||||||
fn from(vec: Vec<u8>) -> Self {
|
fn from(vec: Vec<u8>) -> Self {
|
||||||
Self::Bytes(Bytes::from(vec))
|
Self::Bytes {
|
||||||
|
body: Bytes::from(vec),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B> From<String> for AnyBody<B> {
|
impl<B> From<String> for AnyBody<B> {
|
||||||
fn from(string: String) -> Self {
|
fn from(string: String) -> Self {
|
||||||
Self::Bytes(Bytes::from(string))
|
Self::Bytes {
|
||||||
|
body: Bytes::from(string),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B> From<&'_ String> for AnyBody<B> {
|
impl<B> From<&'_ String> for AnyBody<B> {
|
||||||
fn from(string: &String) -> Self {
|
fn from(string: &String) -> Self {
|
||||||
Self::Bytes(Bytes::copy_from_slice(AsRef::<[u8]>::as_ref(&string)))
|
Self::Bytes {
|
||||||
|
body: Bytes::copy_from_slice(AsRef::<[u8]>::as_ref(&string)),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,22 +198,24 @@ impl<B> From<Cow<'_, str>> for AnyBody<B> {
|
||||||
fn from(string: Cow<'_, str>) -> Self {
|
fn from(string: Cow<'_, str>) -> Self {
|
||||||
match string {
|
match string {
|
||||||
Cow::Owned(s) => Self::from(s),
|
Cow::Owned(s) => Self::from(s),
|
||||||
Cow::Borrowed(s) => {
|
Cow::Borrowed(s) => Self::Bytes {
|
||||||
Self::Bytes(Bytes::copy_from_slice(AsRef::<[u8]>::as_ref(s)))
|
body: Bytes::copy_from_slice(AsRef::<[u8]>::as_ref(s)),
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B> From<Bytes> for AnyBody<B> {
|
impl<B> From<Bytes> for AnyBody<B> {
|
||||||
fn from(bytes: Bytes) -> Self {
|
fn from(bytes: Bytes) -> Self {
|
||||||
Self::Bytes(bytes)
|
Self::Bytes { body: bytes }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<B> From<BytesMut> for AnyBody<B> {
|
impl<B> From<BytesMut> for AnyBody<B> {
|
||||||
fn from(bytes: BytesMut) -> Self {
|
fn from(bytes: BytesMut) -> Self {
|
||||||
Self::Bytes(bytes.freeze())
|
Self::Bytes {
|
||||||
|
body: bytes.freeze(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ mod tests {
|
||||||
impl TestAnyBody {
|
impl TestAnyBody {
|
||||||
pub(crate) fn get_ref(&self) -> &[u8] {
|
pub(crate) fn get_ref(&self) -> &[u8] {
|
||||||
match *self {
|
match *self {
|
||||||
AnyBody::Bytes(ref bin) => bin,
|
AnyBody::Bytes { ref body } => body,
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -168,10 +168,18 @@ mod tests {
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
async fn test_body_eq() {
|
async fn test_body_eq() {
|
||||||
assert!(
|
assert!(
|
||||||
AnyBody::Bytes(Bytes::from_static(b"1"))
|
AnyBody::Bytes {
|
||||||
== AnyBody::Bytes(Bytes::from_static(b"1"))
|
body: Bytes::from_static(b"1")
|
||||||
|
} == AnyBody::Bytes {
|
||||||
|
body: Bytes::from_static(b"1")
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
AnyBody::Bytes {
|
||||||
|
body: Bytes::from_static(b"1")
|
||||||
|
} != AnyBody::None
|
||||||
);
|
);
|
||||||
assert!(AnyBody::Bytes(Bytes::from_static(b"1")) != AnyBody::None);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_rt::test]
|
#[actix_rt::test]
|
||||||
|
|
|
@ -95,7 +95,7 @@ where
|
||||||
};
|
};
|
||||||
|
|
||||||
let body_opt = match body {
|
let body_opt = match body {
|
||||||
AnyBody::Bytes(ref b) => Some(b.clone()),
|
AnyBody::Bytes { ref body } => Some(body.clone()),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -192,7 +192,9 @@ where
|
||||||
let body_new = if is_redirect {
|
let body_new = if is_redirect {
|
||||||
// try to reuse body
|
// try to reuse body
|
||||||
match body {
|
match body {
|
||||||
Some(ref bytes) => AnyBody::Bytes(bytes.clone()),
|
Some(ref bytes) => AnyBody::Bytes {
|
||||||
|
body: bytes.clone(),
|
||||||
|
},
|
||||||
// TODO: should this be AnyBody::Empty or AnyBody::None.
|
// TODO: should this be AnyBody::Empty or AnyBody::None.
|
||||||
_ => AnyBody::empty(),
|
_ => AnyBody::empty(),
|
||||||
}
|
}
|
||||||
|
|
|
@ -236,7 +236,9 @@ impl RequestSender {
|
||||||
response_decompress,
|
response_decompress,
|
||||||
timeout,
|
timeout,
|
||||||
config,
|
config,
|
||||||
AnyBody::Bytes(Bytes::from(body)),
|
AnyBody::Bytes {
|
||||||
|
body: Bytes::from(body),
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,7 +267,9 @@ impl RequestSender {
|
||||||
response_decompress,
|
response_decompress,
|
||||||
timeout,
|
timeout,
|
||||||
config,
|
config,
|
||||||
AnyBody::Bytes(Bytes::from(body)),
|
AnyBody::Bytes {
|
||||||
|
body: Bytes::from(body),
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue