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

This commit is contained in:
fakeshadow 2020-12-15 19:08:06 +08:00
parent fabc68659b
commit 936e12cc9d
9 changed files with 132 additions and 94 deletions

View File

@ -125,8 +125,9 @@ impl Files {
/// Set custom directory renderer /// Set custom directory renderer
pub fn files_listing_renderer<F>(mut self, f: F) -> Self pub fn files_listing_renderer<F>(mut self, f: F) -> Self
where where
for<'r, 's> F: Fn(&'r Directory, &'s HttpRequest) -> Result<ServiceResponse, io::Error> for<'r, 's> F:
+ 'static, Fn(&'r Directory, &'s HttpRequest) -> Result<ServiceResponse, io::Error>
+ 'static,
{ {
self.renderer = Rc::new(f); self.renderer = Rc::new(f);
self self
@ -200,11 +201,11 @@ impl Files {
where where
F: IntoServiceFactory<U>, F: IntoServiceFactory<U>,
U: ServiceFactory< U: ServiceFactory<
Config = (), Config = (),
Request = ServiceRequest, Request = ServiceRequest,
Response = ServiceResponse, Response = ServiceResponse,
Error = Error, Error = Error,
> + 'static, > + 'static,
{ {
// create and configure default resource // create and configure default resource
self.default = Rc::new(RefCell::new(Some(Rc::new(boxed::factory( self.default = Rc::new(RefCell::new(Some(Rc::new(boxed::factory(

View File

@ -62,10 +62,10 @@ impl Connector<(), ()> {
#[allow(clippy::new_ret_no_self, clippy::let_unit_value)] #[allow(clippy::new_ret_no_self, clippy::let_unit_value)]
pub fn new() -> Connector< pub fn new() -> Connector<
impl Service< impl Service<
Request = TcpConnect<Uri>, Request = TcpConnect<Uri>,
Response = TcpConnection<Uri, TcpStream>, Response = TcpConnection<Uri, TcpStream>,
Error = actix_connect::ConnectError, Error = actix_connect::ConnectError,
> + Clone, > + Clone,
TcpStream, TcpStream,
> { > {
Connector { Connector {
@ -117,10 +117,10 @@ impl<T, U> Connector<T, U> {
where where
U1: AsyncRead + AsyncWrite + Unpin + fmt::Debug, U1: AsyncRead + AsyncWrite + Unpin + fmt::Debug,
T1: Service< T1: Service<
Request = TcpConnect<Uri>, Request = TcpConnect<Uri>,
Response = TcpConnection<Uri, U1>, Response = TcpConnection<Uri, U1>,
Error = actix_connect::ConnectError, Error = actix_connect::ConnectError,
> + Clone, > + Clone,
{ {
Connector { Connector {
connector, connector,
@ -135,10 +135,10 @@ impl<T, U> Connector<T, U>
where where
U: AsyncRead + AsyncWrite + Unpin + fmt::Debug + 'static, U: AsyncRead + AsyncWrite + Unpin + fmt::Debug + 'static,
T: Service< T: Service<
Request = TcpConnect<Uri>, Request = TcpConnect<Uri>,
Response = TcpConnection<Uri, U>, Response = TcpConnection<Uri, U>,
Error = actix_connect::ConnectError, Error = actix_connect::ConnectError,
> + Clone > + Clone
+ 'static, + 'static,
{ {
/// Connection timeout, i.e. max time to connect to remote host including dns name resolution. /// Connection timeout, i.e. max time to connect to remote host including dns name resolution.

View File

@ -270,11 +270,11 @@ where
where where
F: IntoServiceFactory<U>, F: IntoServiceFactory<U>,
U: ServiceFactory< U: ServiceFactory<
Config = (), Config = (),
Request = ServiceRequest, Request = ServiceRequest,
Response = ServiceResponse, Response = ServiceResponse,
Error = Error, Error = Error,
> + 'static, > + 'static,
U::InitError: fmt::Debug, U::InitError: fmt::Debug,
{ {
// create and configure default resource // create and configure default resource

View File

@ -107,12 +107,12 @@ impl AppService {
) where ) where
F: IntoServiceFactory<S>, F: IntoServiceFactory<S>,
S: ServiceFactory< S: ServiceFactory<
Config = (), Config = (),
Request = ServiceRequest, Request = ServiceRequest,
Response = ServiceResponse, Response = ServiceResponse,
Error = Error, Error = Error,
InitError = (), InitError = (),
> + 'static, > + 'static,
{ {
self.services.push(( self.services.push((
rdef, rdef,

View File

@ -4,7 +4,7 @@ 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 crate::dev::Payload; use crate::dev::Payload;
use crate::request::HttpRequest; use crate::request::HttpRequest;
@ -95,21 +95,40 @@ 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> {
match self.project().fut.poll(cx) {
Poll::Ready(Ok(t)) => Poll::Ready(Ok(Some(t))),
Poll::Ready(Err(e)) => {
log::debug!("Error for Option<T> extractor: {}", e.into());
Poll::Ready(Ok(None))
}
Poll::Pending => Poll::Pending,
}
} }
} }
@ -165,29 +184,47 @@ 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> {
match self.project().fut.poll(cx) {
Poll::Ready(Ok(t)) => Poll::Ready(Ok(Ok(t))),
Poll::Ready(Err(e)) => Poll::Ready(Ok(Err(e))),
Poll::Pending => Poll::Pending,
}
} }
} }
#[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(()))
} }
} }

View File

@ -164,10 +164,10 @@ impl<T: FromRequest, S> Extract<T, S> {
impl<T: FromRequest, S> ServiceFactory for Extract<T, S> impl<T: FromRequest, S> ServiceFactory for Extract<T, S>
where where
S: Service< S: Service<
Request = (T, HttpRequest), Request = (T, HttpRequest),
Response = ServiceResponse, Response = ServiceResponse,
Error = Infallible, Error = Infallible,
> + Clone, > + Clone,
{ {
type Config = (); type Config = ();
type Request = ServiceRequest; type Request = ServiceRequest;
@ -193,10 +193,10 @@ pub struct ExtractService<T: FromRequest, S> {
impl<T: FromRequest, S> Service for ExtractService<T, S> impl<T: FromRequest, S> Service for ExtractService<T, S>
where where
S: Service< S: Service<
Request = (T, HttpRequest), Request = (T, HttpRequest),
Response = ServiceResponse, Response = ServiceResponse,
Error = Infallible, Error = Infallible,
> + Clone, > + Clone,
{ {
type Request = ServiceRequest; type Request = ServiceRequest;
type Response = ServiceResponse; type Response = ServiceResponse;

View File

@ -347,11 +347,11 @@ where
where where
F: IntoServiceFactory<U>, F: IntoServiceFactory<U>,
U: ServiceFactory< U: ServiceFactory<
Config = (), Config = (),
Request = ServiceRequest, Request = ServiceRequest,
Response = ServiceResponse, Response = ServiceResponse,
Error = Error, Error = Error,
> + 'static, > + 'static,
U::InitError: fmt::Debug, U::InitError: fmt::Debug,
{ {
// create and configure default resource // create and configure default resource
@ -368,12 +368,12 @@ where
impl<T> HttpServiceFactory for Resource<T> impl<T> HttpServiceFactory for Resource<T>
where where
T: ServiceFactory< T: ServiceFactory<
Config = (), Config = (),
Request = ServiceRequest, Request = ServiceRequest,
Response = ServiceResponse, Response = ServiceResponse,
Error = Error, Error = Error,
InitError = (), InitError = (),
> + 'static, > + 'static,
{ {
fn register(mut self, config: &mut AppService) { fn register(mut self, config: &mut AppService) {
let guards = if self.guards.is_empty() { let guards = if self.guards.is_empty() {

View File

@ -287,11 +287,11 @@ where
where where
F: IntoServiceFactory<U>, F: IntoServiceFactory<U>,
U: ServiceFactory< U: ServiceFactory<
Config = (), Config = (),
Request = ServiceRequest, Request = ServiceRequest,
Response = ServiceResponse, Response = ServiceResponse,
Error = Error, Error = Error,
> + 'static, > + 'static,
U::InitError: fmt::Debug, U::InitError: fmt::Debug,
{ {
// create and configure default resource // create and configure default resource
@ -410,12 +410,12 @@ where
impl<T> HttpServiceFactory for Scope<T> impl<T> HttpServiceFactory for Scope<T>
where where
T: ServiceFactory< T: ServiceFactory<
Config = (), Config = (),
Request = ServiceRequest, Request = ServiceRequest,
Response = ServiceResponse, Response = ServiceResponse,
Error = Error, Error = Error,
InitError = (), InitError = (),
> + 'static, > + 'static,
{ {
fn register(mut self, config: &mut AppService) { fn register(mut self, config: &mut AppService) {
// update default resource if needed // update default resource if needed

View File

@ -488,12 +488,12 @@ impl WebService {
where where
F: IntoServiceFactory<T>, F: IntoServiceFactory<T>,
T: ServiceFactory< T: ServiceFactory<
Config = (), Config = (),
Request = ServiceRequest, Request = ServiceRequest,
Response = ServiceResponse, Response = ServiceResponse,
Error = Error, Error = Error,
InitError = (), InitError = (),
> + 'static, > + 'static,
{ {
WebServiceImpl { WebServiceImpl {
srv: service.into_factory(), srv: service.into_factory(),
@ -514,12 +514,12 @@ struct WebServiceImpl<T> {
impl<T> HttpServiceFactory for WebServiceImpl<T> impl<T> HttpServiceFactory for WebServiceImpl<T>
where where
T: ServiceFactory< T: ServiceFactory<
Config = (), Config = (),
Request = ServiceRequest, Request = ServiceRequest,
Response = ServiceResponse, Response = ServiceResponse,
Error = Error, Error = Error,
InitError = (), InitError = (),
> + 'static, > + 'static,
{ {
fn register(mut self, config: &mut AppService) { fn register(mut self, config: &mut AppService) {
let guards = if self.guards.is_empty() { let guards = if self.guards.is_empty() {