diff --git a/actix-service/CHANGES.md b/actix-service/CHANGES.md index e8f3df6c..616fd0ba 100644 --- a/actix-service/CHANGES.md +++ b/actix-service/CHANGES.md @@ -6,10 +6,14 @@ * Add `Transform::from_err()` combinator -* Add `apply_fn` and `apply_fn_factory` helpers +* Add `apply_fn` helper + +* Add `apply_fn_factory` helper * Add `apply_transform` helper +* Add `apply_cfg` helper + ## [0.3.3] - 2019-03-09 diff --git a/actix-service/Cargo.toml b/actix-service/Cargo.toml index 68ba8969..aa47c31e 100644 --- a/actix-service/Cargo.toml +++ b/actix-service/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-service" -version = "0.3.3" +version = "0.3.4" authors = ["Nikolay Kim "] description = "Actix Service" keywords = ["network", "framework", "async", "futures"] @@ -27,4 +27,4 @@ futures = "0.1.24" void = "1.0.2" [dev-dependencies] -actix-rt = "0.1" \ No newline at end of file +actix-rt = "0.2" \ No newline at end of file diff --git a/actix-service/src/apply_cfg.rs b/actix-service/src/apply_cfg.rs index a96663ea..66018b07 100644 --- a/actix-service/src/apply_cfg.rs +++ b/actix-service/src/apply_cfg.rs @@ -1,121 +1,70 @@ use std::marker::PhantomData; -use futures::{Async, Future, Poll}; - -use crate::and_then::AndThen; use crate::{IntoNewService, NewService}; -/// `ApplyNewService` new service combinator -pub struct ApplyConfig { - a: A, - b: B, +/// Create new ApplyConfig` service factory combinator +pub fn apply_cfg(f: F, service: U) -> ApplyConfig +where + S: NewService, + F: Fn(&C1) -> C2, + U: IntoNewService, +{ + ApplyConfig::new(service.into_new_service(), f) +} + +/// `ApplyConfig` service factory combinator +pub struct ApplyConfig { + s: S, f: F, r: PhantomData<(C1, C2)>, } -impl ApplyConfig +impl ApplyConfig where - A: NewService, - B: NewService, + S: NewService, F: Fn(&C1) -> C2, { - /// Create new `ApplyNewService` new service instance - pub fn new, B1: IntoNewService>( - a: A1, - b: B1, - f: F, - ) -> Self { + /// Create new ApplyConfig` service factory combinator + pub fn new>(a: U, f: F) -> Self { Self { f, - a: a.into_new_service(), - b: b.into_new_service(), + s: a.into_new_service(), r: PhantomData, } } } -impl Clone for ApplyConfig +impl Clone for ApplyConfig where - A: Clone, - B: Clone, + S: Clone, F: Clone, { fn clone(&self) -> Self { Self { - a: self.a.clone(), - b: self.b.clone(), + s: self.s.clone(), f: self.f.clone(), r: PhantomData, } } } -impl NewService for ApplyConfig +impl NewService for ApplyConfig where - A: NewService, - B: NewService, + S: NewService, F: Fn(&C1) -> C2, { - type Request = A::Request; - type Response = B::Response; - type Error = A::Error; - type Service = AndThen; + type Request = S::Request; + type Response = S::Response; + type Error = S::Error; + type Service = S::Service; - type InitError = A::InitError; - type Future = ApplyConfigResponse; + type InitError = S::InitError; + type Future = S::Future; fn new_service(&self, cfg: &C1) -> Self::Future { let cfg2 = (self.f)(cfg); - ApplyConfigResponse { - a: None, - b: None, - fut_a: self.a.new_service(cfg), - fut_b: self.b.new_service(&cfg2), - } - } -} - -pub struct ApplyConfigResponse -where - A: NewService, - B: NewService, -{ - fut_b: B::Future, - fut_a: A::Future, - a: Option, - b: Option, -} - -impl Future for ApplyConfigResponse -where - A: NewService, - B: NewService, -{ - type Item = AndThen; - type Error = A::InitError; - - fn poll(&mut self) -> Poll { - if self.a.is_none() { - if let Async::Ready(service) = self.fut_a.poll()? { - self.a = Some(service); - } - } - - if self.b.is_none() { - if let Async::Ready(service) = self.fut_b.poll()? { - self.b = Some(service); - } - } - - if self.a.is_some() && self.b.is_some() { - Ok(Async::Ready(AndThen::new( - self.a.take().unwrap(), - self.b.take().unwrap(), - ))) - } else { - Ok(Async::NotReady) - } + self.s.new_service(&cfg2) } } diff --git a/actix-service/src/lib.rs b/actix-service/src/lib.rs index 052c53a2..1f441266 100644 --- a/actix-service/src/lib.rs +++ b/actix-service/src/lib.rs @@ -40,7 +40,8 @@ pub use self::and_then::{AndThen, AndThenNewService}; use self::and_then_apply::AndThenTransform; use self::and_then_apply_fn::{AndThenApply, AndThenApplyNewService}; pub use self::apply::{apply_fn, apply_fn_factory}; -pub use self::apply_cfg::ApplyConfig; +pub use self::apply_cfg::apply_cfg; +use self::apply_cfg::ApplyConfig; pub use self::fn_service::{fn_cfg_factory, fn_factory, fn_service, FnService}; pub use self::fn_transform::fn_transform; pub use self::from_err::{FromErr, FromErrNewService}; @@ -257,19 +258,23 @@ pub trait NewService { /// Map this service's config type to a different config, /// and use for nested service - fn apply_cfg(self, service: B1, f: F) -> ApplyConfig + fn apply_cfg( + self, + service: U, + f: F, + ) -> AndThenNewService, Config> where Self: Sized, F: Fn(&Config) -> C, - B1: IntoNewService, - B: NewService< + U: IntoNewService, + S: NewService< C, Request = Self::Response, Error = Self::Error, InitError = Self::InitError, >, { - ApplyConfig::new(self, service, f) + self.and_then(ApplyConfig::new(service, f)) } /// Call another service after call to this one has resolved successfully.