keep future impl for response

This commit is contained in:
Rob Ede 2021-05-07 11:59:46 +01:00
parent 310506b257
commit 274a3a9c07
No known key found for this signature in database
GPG Key ID: 97C636207D3EF933
8 changed files with 75 additions and 66 deletions

View File

@ -9,6 +9,7 @@
### Changed
* The `MessageBody` trait now has an associated `Error` type. [#2183]
* Places in `Response` where `ResponseBody<B>` was received or returned now simply use `B`. [#2201]
* `header` mod is now public. [#2171]
* `uri` mod is now public. [#2171]
* Update `language-tags` to `0.3`.
@ -17,12 +18,12 @@
### Removed
* Stop re-exporting `http` crate's `HeaderMap` types in addition to ours. [#2171]
* Down-casting for `MessageBody` types. [#2183]
* `error::Result` alias. [#????]
* `error::Result` alias. [#2201]
[#2171]: https://github.com/actix/actix-web/pull/2171
[#2183]: https://github.com/actix/actix-web/pull/2183
[#2196]: https://github.com/actix/actix-web/pull/2196
[#????]: https://github.com/actix/actix-web/pull/????
[#2201]: https://github.com/actix/actix-web/pull/2201
## 3.0.0-beta.6 - 2021-04-17

View File

@ -389,6 +389,14 @@ impl BoxedResponseHead {
pub fn new(status: StatusCode) -> Self {
RESPONSE_POOL.with(|p| p.get_message(status))
}
// used in: impl Future for Response
#[allow(dead_code)]
pub(crate) fn take(&mut self) -> Self {
BoxedResponseHead {
head: self.head.take(),
}
}
}
impl std::ops::Deref for BoxedResponseHead {

View File

@ -19,7 +19,7 @@ use crate::{
/// An HTTP response.
pub struct Response<B> {
pub(crate) head: BoxedResponseHead,
pub(crate) body: B,
pub(crate) body: Option<B>,
pub(crate) error: Option<Error>,
}
@ -29,7 +29,7 @@ impl Response<Body> {
pub fn new(status: StatusCode) -> Response<Body> {
Response {
head: BoxedResponseHead::new(status),
body: Body::Empty,
body: Some(Body::Empty),
error: None,
}
}
@ -79,19 +79,6 @@ impl Response<Body> {
resp.error = Some(error);
resp
}
// /// Convert response to response with body
// pub fn into_body<B>(self) -> Response<B> {
// let b = match self.body {
// ResponseBody::Body(b) => b,
// ResponseBody::Other(b) => b,
// };
// Response {
// head: self.head,
// error: self.error,
// body: ResponseBody::Other(b),
// }
// }
}
impl<B> Response<B> {
@ -100,7 +87,7 @@ impl<B> Response<B> {
pub fn with_body(status: StatusCode, body: B) -> Response<B> {
Response {
head: BoxedResponseHead::new(status),
body,
body: Some(body),
error: None,
}
}
@ -173,14 +160,14 @@ impl<B> Response<B> {
/// Get body of this response
#[inline]
pub fn body(&self) -> &B {
&self.body
self.body.as_ref().unwrap()
}
/// Set a body
pub fn set_body<B2>(self, body: B2) -> Response<B2> {
Response {
head: self.head,
body,
body: Some(body),
error: None,
}
}
@ -190,10 +177,10 @@ impl<B> Response<B> {
(
Response {
head: self.head,
body: (),
body: Some(()),
error: self.error,
},
self.body,
self.body.unwrap(),
)
}
@ -201,7 +188,7 @@ impl<B> Response<B> {
pub fn drop_body(self) -> Response<()> {
Response {
head: self.head,
body: (),
body: Some(()),
error: None,
}
}
@ -211,10 +198,10 @@ impl<B> Response<B> {
(
Response {
head: self.head,
body,
body: Some(body),
error: self.error,
},
self.body,
self.body.unwrap(),
)
}
@ -223,11 +210,11 @@ impl<B> Response<B> {
where
F: FnOnce(&mut ResponseHead, B) -> B2,
{
let body = f(&mut self.head, self.body);
let body = f(&mut self.head, self.body.unwrap());
Response {
body,
head: self.head,
body: Some(body),
error: self.error,
}
}
@ -239,7 +226,7 @@ impl<B> Response<B> {
/// Extract response body
pub fn into_body(self) -> B {
self.body
self.body.unwrap()
}
}
@ -260,23 +247,41 @@ where
for (key, val) in self.head.headers.iter() {
let _ = writeln!(f, " {:?}: {:?}", key, val);
}
let _ = writeln!(f, " body: {:?}", self.body.size());
let _ = writeln!(f, " body: {:?}", self.body.as_ref().unwrap().size());
res
}
}
// TODO: document why this is needed
// impl<B: Unpin> Future for Response<B> {
// type Output = Result<Response<B>, Infallible>;
impl<B: Default> Default for Response<B> {
#[inline]
fn default() -> Response<B> {
Response::with_body(StatusCode::default(), B::default())
}
}
// fn poll(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Self::Output> {
// Poll::Ready(Ok(Response {
// head: self.head.take(),
// body: self.body.take_body(),
// error: self.error.take(),
// }))
// }
// }
mod fut {
use std::{
convert::Infallible,
future::Future,
pin::Pin,
task::{Context, Poll},
};
use super::*;
// TODO: document why this is needed
impl<B: Unpin> Future for Response<B> {
type Output = Result<Response<B>, Infallible>;
fn poll(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Self::Output> {
Poll::Ready(Ok(Response {
head: self.head.take(),
body: self.body.take(),
error: self.error.take(),
}))
}
}
}
/// Helper converters
impl<I: Into<Response<Body>>, E: Into<Error>> From<Result<I, E>> for Response<Body> {

View File

@ -251,7 +251,7 @@ impl ResponseBuilder {
Response {
head: response,
body,
body: Some(body),
error: None,
}
}

View File

@ -2,7 +2,6 @@ use std::{
cell::{Ref, RefMut},
fmt,
future::Future,
mem,
pin::Pin,
task::{Context, Poll},
};
@ -12,6 +11,7 @@ use actix_http::{
http::{header::HeaderMap, StatusCode},
Extensions, Response, ResponseHead,
};
use futures_core::ready;
#[cfg(feature = "cookies")]
use {
@ -56,14 +56,6 @@ impl HttpResponse<Body> {
error: Some(error),
}
}
// /// Convert response to response with body
// pub fn into_body<B>(self) -> HttpResponse<B> {
// HttpResponse {
// res: self.res.into_body(),
// error: self.error,
// }
// }
}
impl<B> HttpResponse<B> {
@ -279,26 +271,28 @@ impl<B> From<HttpResponse<B>> for Response<B> {
// TODO: expose cause somewhere?
// if let Some(err) = res.error {
// eprintln!("impl<B> From<HttpResponse<B>> for Response<B> let Some(err)");
// return Response::from_error(err).into_body();
// return Response::from_error(err);
// }
res.res
}
}
impl Future for HttpResponse {
type Output = Result<Response<Body>, Error>;
impl<B: Unpin> Future for HttpResponse<B> {
type Output = Result<Response<B>, Error>;
fn poll(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Self::Output> {
// if let Some(err) = self.error.take() {
// return Poll::Ready(Ok(Response::from_error(err).into_body()));
// }
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
if let Some(err) = self.error.take() {
return Poll::Ready(Err(err));
}
Poll::Ready(Ok(mem::replace(
&mut self.res,
Response::new(StatusCode::default()),
)))
let res = &mut self.res;
actix_rt::pin!(res);
match ready!(res.poll(cx)) {
Ok(val) => Poll::Ready(Ok(val)),
Err(err) => Poll::Ready(Err(err.into())),
}
}
}

View File

@ -578,7 +578,7 @@ mod tests {
use actix_utils::future::ok;
use bytes::Bytes;
use crate::dev::{Body};
use crate::dev::Body;
use crate::http::{header, HeaderValue, Method, StatusCode};
use crate::middleware::DefaultHeaders;
use crate::service::ServiceRequest;

View File

@ -4,9 +4,10 @@ use std::{net::SocketAddr, rc::Rc};
pub use actix_http::test::TestBuffer;
use actix_http::{
body,
http::{header::IntoHeaderPair, Method, StatusCode, Uri, Version},
test::TestRequest as HttpTestRequest,
Extensions, Request, body
Extensions, Request,
};
use actix_router::{Path, ResourceDef, Url};
use actix_service::{IntoService, IntoServiceFactory, Service, ServiceFactory};