From 93161df141544277b1f7c983a5c3a616cfd44dd3 Mon Sep 17 00:00:00 2001 From: fakeshadow <24548779@qq.com> Date: Tue, 5 Jan 2021 07:47:38 +0800 Subject: [PATCH] clean up body type (#1872) --- actix-http/src/body.rs | 52 ++++++++++++++++-------------------------- 1 file changed, 20 insertions(+), 32 deletions(-) diff --git a/actix-http/src/body.rs b/actix-http/src/body.rs index 9636f2941..5d1cf7329 100644 --- a/actix-http/src/body.rs +++ b/actix-http/src/body.rs @@ -1,4 +1,3 @@ -use std::marker::PhantomData; use std::pin::Pin; use std::task::{Context, Poll}; use std::{fmt, mem}; @@ -68,7 +67,7 @@ impl MessageBody for Box { #[pin_project(project = ResponseBodyProj)] pub enum ResponseBody { Body(#[pin] B), - Other(#[pin] Body), + Other(Body), } impl ResponseBody { @@ -110,7 +109,7 @@ impl MessageBody for ResponseBody { ) -> Poll>> { match self.project() { ResponseBodyProj::Body(body) => body.poll_next(cx), - ResponseBodyProj::Other(body) => body.poll_next(cx), + ResponseBodyProj::Other(body) => Pin::new(body).poll_next(cx), } } } @@ -124,12 +123,11 @@ impl Stream for ResponseBody { ) -> Poll> { match self.project() { ResponseBodyProj::Body(body) => body.poll_next(cx), - ResponseBodyProj::Other(body) => body.poll_next(cx), + ResponseBodyProj::Other(body) => Pin::new(body).poll_next(cx), } } } -#[pin_project(project = BodyProj)] /// Represents various types of http message body. pub enum Body { /// Empty response. `Content-Length` header is not set. @@ -168,10 +166,10 @@ impl MessageBody for Body { self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll>> { - match self.project() { - BodyProj::None => Poll::Ready(None), - BodyProj::Empty => Poll::Ready(None), - BodyProj::Bytes(ref mut bin) => { + match self.get_mut() { + Body::None => Poll::Ready(None), + Body::Empty => Poll::Ready(None), + Body::Bytes(ref mut bin) => { let len = bin.len(); if len == 0 { Poll::Ready(None) @@ -179,7 +177,7 @@ impl MessageBody for Body { Poll::Ready(Some(Ok(mem::take(bin)))) } } - BodyProj::Message(ref mut body) => Pin::new(body.as_mut()).poll_next(cx), + Body::Message(body) => Pin::new(&mut **body).poll_next(cx), } } } @@ -266,12 +264,12 @@ where } } -impl From> for Body +impl From> for Body where S: Stream> + Unpin + 'static, E: Into + 'static, { - fn from(s: BodyStream) -> Body { + fn from(s: BodyStream) -> Body { Body::from_message(s) } } @@ -367,27 +365,21 @@ impl MessageBody for String { /// Type represent streaming body. /// Response does not contain `content-length` header and appropriate transfer encoding is used. -#[pin_project] -pub struct BodyStream { - #[pin] +pub struct BodyStream { stream: S, - _phantom: PhantomData, } -impl BodyStream +impl BodyStream where S: Stream> + Unpin, E: Into, { pub fn new(stream: S) -> Self { - BodyStream { - stream, - _phantom: PhantomData, - } + BodyStream { stream } } } -impl MessageBody for BodyStream +impl MessageBody for BodyStream where S: Stream> + Unpin, E: Into, @@ -402,13 +394,12 @@ where /// ended on a zero-length chunk, but rather proceed until the underlying /// [`Stream`] ends. fn poll_next( - self: Pin<&mut Self>, + mut self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll>> { - let mut stream = self.project().stream; loop { - let stream = stream.as_mut(); - return Poll::Ready(match ready!(stream.poll_next(cx)) { + let stream = &mut self.as_mut().stream; + return Poll::Ready(match ready!(Pin::new(stream).poll_next(cx)) { Some(Ok(ref bytes)) if bytes.is_empty() => continue, opt => opt.map(|res| res.map_err(Into::into)), }); @@ -418,10 +409,8 @@ where /// Type represent streaming body. This body implementation should be used /// if total size of stream is known. Data get sent as is without using transfer encoding. -#[pin_project] pub struct SizedStream { size: u64, - #[pin] stream: S, } @@ -448,13 +437,12 @@ where /// ended on a zero-length chunk, but rather proceed until the underlying /// [`Stream`] ends. fn poll_next( - self: Pin<&mut Self>, + mut self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll>> { - let mut stream: Pin<&mut S> = self.project().stream; loop { - let stream = stream.as_mut(); - return Poll::Ready(match ready!(stream.poll_next(cx)) { + let stream = &mut self.as_mut().stream; + return Poll::Ready(match ready!(Pin::new(stream).poll_next(cx)) { Some(Ok(ref bytes)) if bytes.is_empty() => continue, val => val, });