rename Stream variant to Body

This commit is contained in:
Rob Ede 2021-11-16 16:13:45 +00:00
parent 8d2cfd0a15
commit 5167bf16a2
No known key found for this signature in database
GPG Key ID: 97C636207D3EF933
6 changed files with 46 additions and 20 deletions

View File

@ -1,6 +1,10 @@
# Changes # Changes
## Unreleased - 2021-xx-xx ## Unreleased - 2021-xx-xx
### Fixed
* Relax `Unpin` bound on `S` (stream) parameter of `HttpResponseBuilder::streaming`. [#????]
[#2423]: https://github.com/actix/actix-web/pull/2423
## 4.0.0-beta.11 - 2021-11-15 ## 4.0.0-beta.11 - 2021-11-15

View File

@ -7,10 +7,11 @@
* `AnyBody::into_boxed` for quickly converting to a type-erased, boxed body type. [#????] * `AnyBody::into_boxed` for quickly converting to a type-erased, boxed body type. [#????]
### Changed ### Changed
* Rename `AnyBody::{Message => Stream}`. [#2446] * Rename `AnyBody::{Message => Body}`. [#2446]
* Rename `AnyBody::{from_message => new_boxed}`. [#????] * Rename `AnyBody::{from_message => new_boxed}`. [#????]
* Rename `AnyBody::{from_slice => copy_from_slice}`. [#????]
* Rename `BoxAnyBody` to `BoxBody` [#????] * Rename `BoxAnyBody` to `BoxBody` [#????]
* Change representation of `AnyBody` to include a type parameter in `Stream` variant. Defaults to `BoxBody`. [#????] * Change representation of `AnyBody` to include a type parameter in `Body` variant. Defaults to `BoxBody`. [#????]
### Removed ### Removed
* `AnyBody::Empty`; an empty body can now only be represented as a zero-length `Bytes` variant. [#2446] * `AnyBody::Empty`; an empty body can now only be represented as a zero-length `Bytes` variant. [#2446]

View File

@ -17,15 +17,15 @@ pub type Body = AnyBody;
/// Represents various types of HTTP message body. /// Represents various types of HTTP message body.
#[derive(Clone)] #[derive(Clone)]
pub enum AnyBody<S = BoxBody> { pub enum AnyBody<B = BoxBody> {
/// Empty response. `Content-Length` header is not set. /// Empty response. `Content-Length` header is not set.
None, None,
/// Specific response body. /// Specific response body.
Bytes(Bytes), Bytes(Bytes),
/// Generic message body. /// Generic / Other message body.
Stream(S), Body(B),
} }
impl AnyBody { impl AnyBody {
@ -40,10 +40,18 @@ impl AnyBody {
B: MessageBody + 'static, B: MessageBody + 'static,
B::Error: Into<Box<dyn StdError + 'static>>, B::Error: Into<Box<dyn StdError + 'static>>,
{ {
Self::Stream(BoxBody::from_body(body)) Self::Body(BoxBody::from_body(body))
} }
/// Create body from slice (copy) /// 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.
pub fn copy_from_slice(s: &[u8]) -> Self {
Self::Bytes(Bytes::copy_from_slice(s))
}
#[doc(hidden)]
#[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(Bytes::copy_from_slice(s))
} }
@ -56,22 +64,22 @@ where
{ {
/// 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::Stream(body) Self::Body(body)
} }
pub fn into_boxed(self) -> AnyBody { pub fn into_boxed(self) -> AnyBody {
match self { match self {
AnyBody::None => AnyBody::new_boxed(()), AnyBody::None => AnyBody::new_boxed(()),
AnyBody::Bytes(body) => AnyBody::new_boxed(body), AnyBody::Bytes(body) => AnyBody::new_boxed(body),
AnyBody::Stream(body) => AnyBody::new_boxed(body), AnyBody::Body(body) => AnyBody::new_boxed(body),
} }
} }
} }
impl<S> MessageBody for AnyBody<S> impl<B> MessageBody for AnyBody<B>
where where
S: MessageBody + Unpin, B: MessageBody + Unpin,
S::Error: StdError + 'static, B::Error: StdError + 'static,
{ {
type Error = Error; type Error = Error;
@ -79,7 +87,7 @@ where
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 bin) => BodySize::Sized(bin.len() as u64),
AnyBody::Stream(ref body) => body.size(), AnyBody::Body(ref body) => body.size(),
} }
} }
@ -98,7 +106,7 @@ where
} }
} }
AnyBody::Stream(body) => Pin::new(body) AnyBody::Body(body) => Pin::new(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)),
} }
@ -113,7 +121,7 @@ impl PartialEq for AnyBody {
AnyBody::Bytes(ref b2) => b == b2, AnyBody::Bytes(ref b2) => b == b2,
_ => false, _ => false,
}, },
AnyBody::Stream(_) => false, AnyBody::Body(_) => false,
} }
} }
} }
@ -123,7 +131,7 @@ impl<S: fmt::Debug> fmt::Debug for AnyBody<S> {
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 bytes) => write!(f, "AnyBody::Bytes({:?})", bytes),
AnyBody::Stream(ref stream) => write!(f, "AnyBody::Message({:?})", stream), AnyBody::Body(ref stream) => write!(f, "AnyBody::Message({:?})", stream),
} }
} }
} }
@ -252,12 +260,25 @@ mod tests {
use static_assertions::{assert_impl_all, assert_not_impl_all}; use static_assertions::{assert_impl_all, assert_not_impl_all};
use super::*; use super::*;
use crate::body::to_bytes;
assert_impl_all!(AnyBody<()>: MessageBody, fmt::Debug, Send, Sync); assert_impl_all!(AnyBody<()>: MessageBody, fmt::Debug, Send, Sync);
assert_impl_all!(AnyBody<AnyBody<()>>: MessageBody, fmt::Debug, Send, Sync);
assert_impl_all!(AnyBody<Bytes>: MessageBody, fmt::Debug, Send, Sync); assert_impl_all!(AnyBody<Bytes>: MessageBody, fmt::Debug, Send, Sync);
assert_impl_all!(AnyBody: MessageBody, fmt::Debug); assert_impl_all!(AnyBody: MessageBody, fmt::Debug);
assert_impl_all!(BoxBody: MessageBody, fmt::Debug); assert_impl_all!(BoxBody: MessageBody, fmt::Debug);
assert_not_impl_all!(AnyBody: Send, Sync); assert_not_impl_all!(AnyBody: Send, Sync);
assert_not_impl_all!(BoxBody: Send, Sync); assert_not_impl_all!(BoxBody: Send, Sync);
#[actix_rt::test]
async fn nested_boxed_body() {
let body = AnyBody::copy_from_slice(&[1, 2, 3]);
let boxed_body = BoxBody::from_body(BoxBody::from_body(body));
assert_eq!(
to_bytes(boxed_body).await.unwrap(),
Bytes::from(vec![1, 2, 3]),
);
}
} }

View File

@ -108,10 +108,10 @@ mod tests {
assert_eq!(Body::from(b"test".as_ref()).size(), BodySize::Sized(4)); assert_eq!(Body::from(b"test".as_ref()).size(), BodySize::Sized(4));
assert_eq!(Body::from(b"test".as_ref()).get_ref(), b"test"); assert_eq!(Body::from(b"test".as_ref()).get_ref(), b"test");
assert_eq!( assert_eq!(
Body::from_slice(b"test".as_ref()).size(), Body::copy_from_slice(b"test".as_ref()).size(),
BodySize::Sized(4) BodySize::Sized(4)
); );
assert_eq!(Body::from_slice(b"test".as_ref()).get_ref(), b"test"); assert_eq!(Body::copy_from_slice(b"test".as_ref()).get_ref(), b"test");
let sb = Bytes::from(&b"test"[..]); let sb = Bytes::from(&b"test"[..]);
pin!(sb); pin!(sb);

View File

@ -68,7 +68,7 @@ impl<B: MessageBody> Encoder<B> {
return ResponseBody::Other(Body::Bytes(buf)); return ResponseBody::Other(Body::Bytes(buf));
} }
} }
Body::Stream(stream) => EncoderBody::BoxedStream(stream), Body::Body(stream) => EncoderBody::BoxedStream(stream),
}, },
ResponseBody::Body(stream) => EncoderBody::Stream(stream), ResponseBody::Body(stream) => EncoderBody::Stream(stream),
}; };

View File

@ -1077,7 +1077,7 @@ mod tests {
fn_service(|req: Request| { fn_service(|req: Request| {
let path = req.path().as_bytes(); let path = req.path().as_bytes();
ready(Ok::<_, Error>( ready(Ok::<_, Error>(
Response::ok().set_body(AnyBody::from_slice(path)), Response::ok().set_body(AnyBody::copy_from_slice(path)),
)) ))
}) })
} }