1
0
mirror of https://github.com/fafhrd91/actix-web synced 2024-11-28 01:52:57 +01:00

remove boxed future for Option<T> and Result<T, E> extract type (#1829)

* remove boxed future for Option<T> and Result<T, E> extract type

* use ready macro

* fix fmt
This commit is contained in:
fakeshadow 2020-12-17 02:34:10 +08:00 committed by GitHub
parent fabc68659b
commit d7ce648445
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -4,7 +4,8 @@ use std::pin::Pin;
use std::task::{Context, Poll}; use std::task::{Context, Poll};
use actix_http::error::Error; use actix_http::error::Error;
use futures_util::future::{ok, FutureExt, LocalBoxFuture, Ready}; use futures_util::future::{ready, Ready};
use futures_util::ready;
use crate::dev::Payload; use crate::dev::Payload;
use crate::request::HttpRequest; use crate::request::HttpRequest;
@ -95,21 +96,41 @@ where
T: FromRequest, T: FromRequest,
T::Future: 'static, T::Future: 'static,
{ {
type Config = T::Config;
type Error = Error; type Error = Error;
type Future = LocalBoxFuture<'static, Result<Option<T>, Error>>; type Future = FromRequestOptFuture<T::Future>;
type Config = T::Config;
#[inline] #[inline]
fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future { fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
T::from_request(req, payload) FromRequestOptFuture {
.then(|r| match r { fut: T::from_request(req, payload),
Ok(v) => ok(Some(v)), }
Err(e) => { }
log::debug!("Error for Option<T> extractor: {}", e.into()); }
ok(None)
} #[pin_project::pin_project]
}) pub struct FromRequestOptFuture<Fut> {
.boxed_local() #[pin]
fut: Fut,
}
impl<Fut, T, E> Future for FromRequestOptFuture<Fut>
where
Fut: Future<Output = Result<T, E>>,
E: Into<Error>,
{
type Output = Result<Option<T>, Error>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.project();
let res = ready!(this.fut.poll(cx));
match res {
Ok(t) => Poll::Ready(Ok(Some(t))),
Err(e) => {
log::debug!("Error for Option<T> extractor: {}", e.into());
Poll::Ready(Ok(None))
}
}
} }
} }
@ -165,29 +186,45 @@ where
T::Error: 'static, T::Error: 'static,
T::Future: 'static, T::Future: 'static,
{ {
type Config = T::Config;
type Error = Error; type Error = Error;
type Future = LocalBoxFuture<'static, Result<Result<T, T::Error>, Error>>; type Future = FromRequestResFuture<T::Future>;
type Config = T::Config;
#[inline] #[inline]
fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future { fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
T::from_request(req, payload) FromRequestResFuture {
.then(|res| match res { fut: T::from_request(req, payload),
Ok(v) => ok(Ok(v)), }
Err(e) => ok(Err(e)), }
}) }
.boxed_local()
#[pin_project::pin_project]
pub struct FromRequestResFuture<Fut> {
#[pin]
fut: Fut,
}
impl<Fut, T, E> Future for FromRequestResFuture<Fut>
where
Fut: Future<Output = Result<T, E>>,
{
type Output = Result<Result<T, E>, Error>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.project();
let res = ready!(this.fut.poll(cx));
Poll::Ready(Ok(res))
} }
} }
#[doc(hidden)] #[doc(hidden)]
impl FromRequest for () { impl FromRequest for () {
type Config = ();
type Error = Error; type Error = Error;
type Future = Ready<Result<(), Error>>; type Future = Ready<Result<(), Error>>;
type Config = ();
fn from_request(_: &HttpRequest, _: &mut Payload) -> Self::Future { fn from_request(_: &HttpRequest, _: &mut Payload) -> Self::Future {
ok(()) ready(Ok(()))
} }
} }