diff --git a/actix-utils/CHANGES.md b/actix-utils/CHANGES.md index 7bc18b4b..a28ef8b4 100644 --- a/actix-utils/CHANGES.md +++ b/actix-utils/CHANGES.md @@ -1,5 +1,12 @@ # Changes +## [0.2.3] - 2019-02-21 + +### Added + +* Add `BoxedNewService` and `BoxedService` + + ## [0.2.2] - 2019-02-11 ### Added diff --git a/actix-utils/Cargo.toml b/actix-utils/Cargo.toml index aa626e03..a69de3ca 100644 --- a/actix-utils/Cargo.toml +++ b/actix-utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-utils" -version = "0.2.2" +version = "0.2.3" authors = ["Nikolay Kim "] description = "Actix utils - various actix net related services" keywords = ["network", "framework", "async", "futures"] diff --git a/actix-utils/src/boxed.rs b/actix-utils/src/boxed.rs new file mode 100644 index 00000000..56cfbdde --- /dev/null +++ b/actix-utils/src/boxed.rs @@ -0,0 +1,102 @@ +use actix_service::{NewService, Service}; +use futures::{Future, Poll}; + +pub type BoxedService = Box< + Service< + Request = Req, + Response = Res, + Error = Err, + Future = Box>, + >, +>; + +pub type BoxedNewService = Box< + NewService< + Request = Req, + Response = Res, + Error = Err, + InitError = InitErr, + Service = BoxedService, + Future = Box, Error = InitErr>>, + >, +>; + +/// Create boxed new service +pub fn new_service( + service: T, +) -> BoxedNewService +where + T: NewService + 'static, + T::Service: 'static, +{ + Box::new(NewServiceWrapper(service)) +} + +/// Create boxed service +pub fn service(service: T) -> BoxedService +where + T: Service + 'static, + T::Future: 'static, +{ + Box::new(ServiceWrapper(service)) +} + +struct NewServiceWrapper(T); + +impl NewService for NewServiceWrapper +where + Req: 'static, + Res: 'static, + Err: 'static, + InitErr: 'static, + T: NewService, + T::Future: 'static, + T::Service: 'static, + ::Future: 'static, +{ + type Request = Req; + type Response = Res; + type Error = Err; + type InitError = InitErr; + type Service = BoxedService; + type Future = Box>; + + fn new_service(&self) -> Self::Future { + Box::new( + self.0 + .new_service() + .map(|service| ServiceWrapper::boxed(service)), + ) + } +} + +struct ServiceWrapper(T); + +impl ServiceWrapper +where + T: Service + 'static, + T::Future: 'static, +{ + fn boxed(service: T) -> BoxedService { + Box::new(ServiceWrapper(service)) + } +} + +impl Service for ServiceWrapper +where + T: Service, + T::Future: 'static, +{ + type Request = Req; + type Response = Res; + type Error = Err; + type Future = Box>; + + fn poll_ready(&mut self) -> Poll<(), Self::Error> { + self.0.poll_ready() + } + + fn call(&mut self, req: Self::Request) -> Self::Future { + Box::new(self.0.call(req)) + } +} diff --git a/actix-utils/src/lib.rs b/actix-utils/src/lib.rs index 15bff92b..bb5443e3 100644 --- a/actix-utils/src/lib.rs +++ b/actix-utils/src/lib.rs @@ -1,4 +1,5 @@ //! Actix utils - various helper services +pub mod boxed; mod cell; pub mod cloneable; pub mod counter;