diff --git a/actix-service/CHANGES.md b/actix-service/CHANGES.md index 20fb2cf8..ac340bb6 100644 --- a/actix-service/CHANGES.md +++ b/actix-service/CHANGES.md @@ -2,8 +2,10 @@ ## Unreleased - 2021-xx-xx * Add default `Service` trait impl for `Rc` and `&S: Service`. [#288] +* Add `boxed::rc_service` function for constructing `boxed::RcService` type [#290] [#288]: https://github.com/actix/actix-net/pull/288 +[#290]: https://github.com/actix/actix-net/pull/290 ## 2.0.0-beta.4 - 2021-02-04 diff --git a/actix-service/src/boxed.rs b/actix-service/src/boxed.rs index 6ad2eaf4..4afaa6c3 100644 --- a/actix-service/src/boxed.rs +++ b/actix-service/src/boxed.rs @@ -1,7 +1,6 @@ -use alloc::boxed::Box; +use alloc::{boxed::Box, rc::Rc}; use core::{ future::Future, - marker::PhantomData, pin::Pin, task::{Context, Poll}, }; @@ -10,12 +9,34 @@ use crate::{Service, ServiceFactory}; pub type BoxFuture = Pin>>; -pub type BoxService = - Box>>>; +macro_rules! service_object { + ($name: ident, $type: tt, $fn_name: ident) => { + /// Type alias for service trait object. + pub type $name = $type< + dyn Service>>, + >; + /// Create service trait object. + pub fn $fn_name(service: S) -> $name + where + S: Service + 'static, + Req: 'static, + S::Future: 'static, + { + $type::new(ServiceWrapper(service)) + } + }; +} + +service_object!(BoxService, Box, service); + +service_object!(RcService, Rc, rc_service); + +/// Type alias for service factory trait object that would produce a trait object service +/// (`BoxService`, `RcService`, etc.) pub struct BoxServiceFactory(Inner); -/// Create boxed service factory +/// Create service factory trait object. pub fn factory( factory: SF, ) -> BoxServiceFactory @@ -28,20 +49,7 @@ where SF::Error: 'static, SF::InitError: 'static, { - BoxServiceFactory(Box::new(FactoryWrapper { - factory, - _t: PhantomData, - })) -} - -/// Create boxed service -pub fn service(service: S) -> BoxService -where - S: Service + 'static, - Req: 'static, - S::Future: 'static, -{ - Box::new(ServiceWrapper(service, PhantomData)) + BoxServiceFactory(Box::new(FactoryWrapper(factory))) } type Inner = Box< @@ -66,9 +74,9 @@ where { type Response = Res; type Error = Err; - type InitError = InitErr; type Config = C; type Service = BoxService; + type InitError = InitErr; type Future = BoxFuture>; @@ -77,12 +85,9 @@ where } } -struct FactoryWrapper { - factory: SF, - _t: PhantomData<(Req, Cfg)>, -} +struct FactoryWrapper(SF); -impl ServiceFactory for FactoryWrapper +impl ServiceFactory for FactoryWrapper where Req: 'static, Res: 'static, @@ -95,34 +100,20 @@ where { type Response = Res; type Error = Err; - type InitError = InitErr; type Config = Cfg; type Service = BoxService; + type InitError = InitErr; type Future = BoxFuture>; fn new_service(&self, cfg: Cfg) -> Self::Future { - let fut = self.factory.new_service(cfg); - Box::pin(async { - let res = fut.await; - res.map(ServiceWrapper::boxed) - }) + let f = self.0.new_service(cfg); + Box::pin(async { f.await.map(|s| Box::new(ServiceWrapper(s)) as _) }) } } -struct ServiceWrapper, Req>(S, PhantomData); +struct ServiceWrapper(S); -impl ServiceWrapper -where - S: Service + 'static, - Req: 'static, - S::Future: 'static, -{ - fn boxed(service: S) -> BoxService { - Box::new(ServiceWrapper(service, PhantomData)) - } -} - -impl Service for ServiceWrapper +impl Service for ServiceWrapper where S: Service, S::Future: 'static, diff --git a/actix-service/src/lib.rs b/actix-service/src/lib.rs index 66132961..a4f6c5b4 100644 --- a/actix-service/src/lib.rs +++ b/actix-service/src/lib.rs @@ -204,18 +204,18 @@ where impl Service for Rc where - S: Service, + S: Service + ?Sized, { type Response = S::Response; type Error = S::Error; type Future = S::Future; fn poll_ready(&self, ctx: &mut Context<'_>) -> Poll> { - (&**self).poll_ready(ctx) + (**self).poll_ready(ctx) } fn call(&self, request: Req) -> S::Future { - (&**self).call(request) + (**self).call(request) } }