From 936e12cc9df02445e118926e6daefb2340960aac Mon Sep 17 00:00:00 2001 From: fakeshadow <24548779@qq.com> Date: Tue, 15 Dec 2020 19:08:06 +0800 Subject: [PATCH] remove boxed future for Option and Result extract type --- actix-files/src/files.rs | 15 +++--- actix-http/src/client/connector.rs | 24 ++++----- src/app.rs | 10 ++-- src/config.rs | 12 ++--- src/extract.rs | 81 ++++++++++++++++++++++-------- src/handler.rs | 16 +++--- src/resource.rs | 22 ++++---- src/scope.rs | 22 ++++---- src/service.rs | 24 ++++----- 9 files changed, 132 insertions(+), 94 deletions(-) diff --git a/actix-files/src/files.rs b/actix-files/src/files.rs index a99b4699e..642579cd5 100644 --- a/actix-files/src/files.rs +++ b/actix-files/src/files.rs @@ -125,8 +125,9 @@ impl Files { /// Set custom directory renderer pub fn files_listing_renderer(mut self, f: F) -> Self where - for<'r, 's> F: Fn(&'r Directory, &'s HttpRequest) -> Result - + 'static, + for<'r, 's> F: + Fn(&'r Directory, &'s HttpRequest) -> Result + + 'static, { self.renderer = Rc::new(f); self @@ -200,11 +201,11 @@ impl Files { where F: IntoServiceFactory, U: ServiceFactory< - Config = (), - Request = ServiceRequest, - Response = ServiceResponse, - Error = Error, - > + 'static, + Config = (), + Request = ServiceRequest, + Response = ServiceResponse, + Error = Error, + > + 'static, { // create and configure default resource self.default = Rc::new(RefCell::new(Some(Rc::new(boxed::factory( diff --git a/actix-http/src/client/connector.rs b/actix-http/src/client/connector.rs index e1aed6382..09cbf5b0f 100644 --- a/actix-http/src/client/connector.rs +++ b/actix-http/src/client/connector.rs @@ -62,10 +62,10 @@ impl Connector<(), ()> { #[allow(clippy::new_ret_no_self, clippy::let_unit_value)] pub fn new() -> Connector< impl Service< - Request = TcpConnect, - Response = TcpConnection, - Error = actix_connect::ConnectError, - > + Clone, + Request = TcpConnect, + Response = TcpConnection, + Error = actix_connect::ConnectError, + > + Clone, TcpStream, > { Connector { @@ -117,10 +117,10 @@ impl Connector { where U1: AsyncRead + AsyncWrite + Unpin + fmt::Debug, T1: Service< - Request = TcpConnect, - Response = TcpConnection, - Error = actix_connect::ConnectError, - > + Clone, + Request = TcpConnect, + Response = TcpConnection, + Error = actix_connect::ConnectError, + > + Clone, { Connector { connector, @@ -135,10 +135,10 @@ impl Connector where U: AsyncRead + AsyncWrite + Unpin + fmt::Debug + 'static, T: Service< - Request = TcpConnect, - Response = TcpConnection, - Error = actix_connect::ConnectError, - > + Clone + Request = TcpConnect, + Response = TcpConnection, + Error = actix_connect::ConnectError, + > + Clone + 'static, { /// Connection timeout, i.e. max time to connect to remote host including dns name resolution. diff --git a/src/app.rs b/src/app.rs index 8dd86f7ec..e5e76b20c 100644 --- a/src/app.rs +++ b/src/app.rs @@ -270,11 +270,11 @@ where where F: IntoServiceFactory, U: ServiceFactory< - Config = (), - Request = ServiceRequest, - Response = ServiceResponse, - Error = Error, - > + 'static, + Config = (), + Request = ServiceRequest, + Response = ServiceResponse, + Error = Error, + > + 'static, U::InitError: fmt::Debug, { // create and configure default resource diff --git a/src/config.rs b/src/config.rs index 01959daa1..3eea23ff0 100644 --- a/src/config.rs +++ b/src/config.rs @@ -107,12 +107,12 @@ impl AppService { ) where F: IntoServiceFactory, S: ServiceFactory< - Config = (), - Request = ServiceRequest, - Response = ServiceResponse, - Error = Error, - InitError = (), - > + 'static, + Config = (), + Request = ServiceRequest, + Response = ServiceResponse, + Error = Error, + InitError = (), + > + 'static, { self.services.push(( rdef, diff --git a/src/extract.rs b/src/extract.rs index df9c34cb3..c13e9da44 100644 --- a/src/extract.rs +++ b/src/extract.rs @@ -4,7 +4,7 @@ use std::pin::Pin; use std::task::{Context, Poll}; 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::request::HttpRequest; @@ -95,21 +95,40 @@ where T: FromRequest, T::Future: 'static, { - type Config = T::Config; type Error = Error; - type Future = LocalBoxFuture<'static, Result, Error>>; + type Future = FromRequestOptFuture; + type Config = T::Config; #[inline] fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future { - T::from_request(req, payload) - .then(|r| match r { - Ok(v) => ok(Some(v)), - Err(e) => { - log::debug!("Error for Option extractor: {}", e.into()); - ok(None) - } - }) - .boxed_local() + FromRequestOptFuture { + fut: T::from_request(req, payload), + } + } +} + +#[pin_project::pin_project] +pub struct FromRequestOptFuture { + #[pin] + fut: Fut, +} + +impl Future for FromRequestOptFuture +where + Fut: Future>, + E: Into, +{ + type Output = Result, Error>; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + match self.project().fut.poll(cx) { + Poll::Ready(Ok(t)) => Poll::Ready(Ok(Some(t))), + Poll::Ready(Err(e)) => { + log::debug!("Error for Option extractor: {}", e.into()); + Poll::Ready(Ok(None)) + } + Poll::Pending => Poll::Pending, + } } } @@ -165,29 +184,47 @@ where T::Error: 'static, T::Future: 'static, { - type Config = T::Config; type Error = Error; - type Future = LocalBoxFuture<'static, Result, Error>>; + type Future = FromRequestResFuture; + type Config = T::Config; #[inline] fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future { - T::from_request(req, payload) - .then(|res| match res { - Ok(v) => ok(Ok(v)), - Err(e) => ok(Err(e)), - }) - .boxed_local() + FromRequestResFuture { + fut: T::from_request(req, payload), + } + } +} + +#[pin_project::pin_project] +pub struct FromRequestResFuture { + #[pin] + fut: Fut, +} + +impl Future for FromRequestResFuture +where + Fut: Future>, +{ + type Output = Result, Error>; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + 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)] impl FromRequest for () { - type Config = (); type Error = Error; type Future = Ready>; + type Config = (); fn from_request(_: &HttpRequest, _: &mut Payload) -> Self::Future { - ok(()) + ready(Ok(())) } } diff --git a/src/handler.rs b/src/handler.rs index 669512ab3..aa015ea6b 100644 --- a/src/handler.rs +++ b/src/handler.rs @@ -164,10 +164,10 @@ impl Extract { impl ServiceFactory for Extract where S: Service< - Request = (T, HttpRequest), - Response = ServiceResponse, - Error = Infallible, - > + Clone, + Request = (T, HttpRequest), + Response = ServiceResponse, + Error = Infallible, + > + Clone, { type Config = (); type Request = ServiceRequest; @@ -193,10 +193,10 @@ pub struct ExtractService { impl Service for ExtractService where S: Service< - Request = (T, HttpRequest), - Response = ServiceResponse, - Error = Infallible, - > + Clone, + Request = (T, HttpRequest), + Response = ServiceResponse, + Error = Infallible, + > + Clone, { type Request = ServiceRequest; type Response = ServiceResponse; diff --git a/src/resource.rs b/src/resource.rs index dd9b23012..7dbea3139 100644 --- a/src/resource.rs +++ b/src/resource.rs @@ -347,11 +347,11 @@ where where F: IntoServiceFactory, U: ServiceFactory< - Config = (), - Request = ServiceRequest, - Response = ServiceResponse, - Error = Error, - > + 'static, + Config = (), + Request = ServiceRequest, + Response = ServiceResponse, + Error = Error, + > + 'static, U::InitError: fmt::Debug, { // create and configure default resource @@ -368,12 +368,12 @@ where impl HttpServiceFactory for Resource where T: ServiceFactory< - Config = (), - Request = ServiceRequest, - Response = ServiceResponse, - Error = Error, - InitError = (), - > + 'static, + Config = (), + Request = ServiceRequest, + Response = ServiceResponse, + Error = Error, + InitError = (), + > + 'static, { fn register(mut self, config: &mut AppService) { let guards = if self.guards.is_empty() { diff --git a/src/scope.rs b/src/scope.rs index 681d142be..013b54756 100644 --- a/src/scope.rs +++ b/src/scope.rs @@ -287,11 +287,11 @@ where where F: IntoServiceFactory, U: ServiceFactory< - Config = (), - Request = ServiceRequest, - Response = ServiceResponse, - Error = Error, - > + 'static, + Config = (), + Request = ServiceRequest, + Response = ServiceResponse, + Error = Error, + > + 'static, U::InitError: fmt::Debug, { // create and configure default resource @@ -410,12 +410,12 @@ where impl HttpServiceFactory for Scope where T: ServiceFactory< - Config = (), - Request = ServiceRequest, - Response = ServiceResponse, - Error = Error, - InitError = (), - > + 'static, + Config = (), + Request = ServiceRequest, + Response = ServiceResponse, + Error = Error, + InitError = (), + > + 'static, { fn register(mut self, config: &mut AppService) { // update default resource if needed diff --git a/src/service.rs b/src/service.rs index 189ba5554..11865fbcc 100644 --- a/src/service.rs +++ b/src/service.rs @@ -488,12 +488,12 @@ impl WebService { where F: IntoServiceFactory, T: ServiceFactory< - Config = (), - Request = ServiceRequest, - Response = ServiceResponse, - Error = Error, - InitError = (), - > + 'static, + Config = (), + Request = ServiceRequest, + Response = ServiceResponse, + Error = Error, + InitError = (), + > + 'static, { WebServiceImpl { srv: service.into_factory(), @@ -514,12 +514,12 @@ struct WebServiceImpl { impl HttpServiceFactory for WebServiceImpl where T: ServiceFactory< - Config = (), - Request = ServiceRequest, - Response = ServiceResponse, - Error = Error, - InitError = (), - > + 'static, + Config = (), + Request = ServiceRequest, + Response = ServiceResponse, + Error = Error, + InitError = (), + > + 'static, { fn register(mut self, config: &mut AppService) { let guards = if self.guards.is_empty() {