diff --git a/actix-service/Cargo.toml b/actix-service/Cargo.toml index 5a06e33a..b50d5ed0 100644 --- a/actix-service/Cargo.toml +++ b/actix-service/Cargo.toml @@ -24,3 +24,4 @@ path = "src/lib.rs" [dependencies] futures = "0.1.24" +void = "1.0.2" diff --git a/actix-service/src/fn_service.rs b/actix-service/src/fn_service.rs index 0faf933a..630b5d34 100644 --- a/actix-service/src/fn_service.rs +++ b/actix-service/src/fn_service.rs @@ -3,7 +3,7 @@ use std::marker::PhantomData; use futures::future::{ok, FutureResult}; use futures::{Async, IntoFuture, Poll}; -use crate::Never; +use crate::Void; use crate::{IntoConfigurableNewService, IntoNewService, IntoService, NewService, Service}; /// Create `NewService` for function that can act as Service @@ -125,7 +125,7 @@ where type Error = Out::Error; type Service = FnService; - type InitError = Never; + type InitError = Void; type Future = FutureResult; fn new_service(&self, _: &Cfg) -> Self::Future { diff --git a/actix-service/src/lib.rs b/actix-service/src/lib.rs index a1eeb617..666d137d 100644 --- a/actix-service/src/lib.rs +++ b/actix-service/src/lib.rs @@ -3,6 +3,8 @@ use std::sync::Arc; use futures::{Future, IntoFuture, Poll}; +pub use void::Void; + mod and_then; mod and_then_apply; mod and_then_apply_fn; @@ -19,6 +21,7 @@ mod map_init_err; mod then; mod transform; mod transform_map_err; +mod transform_map_init_err; pub use self::and_then::{AndThen, AndThenNewService}; use self::and_then_apply::{AndThenTransform, AndThenTransformNewService}; @@ -33,9 +36,6 @@ pub use self::map_init_err::MapInitErr; pub use self::then::{Then, ThenNewService}; pub use self::transform::{IntoNewTransform, IntoTransform, NewTransform, Transform}; -#[derive(Copy, Clone, Debug)] -pub enum Never {} - /// An asynchronous function from `Request` to a `Response`. pub trait Service { /// Requests handled by the service. diff --git a/actix-service/src/transform.rs b/actix-service/src/transform.rs index 127d2ef8..e7357c78 100644 --- a/actix-service/src/transform.rs +++ b/actix-service/src/transform.rs @@ -4,6 +4,7 @@ use std::sync::Arc; use futures::{Future, Poll}; use crate::transform_map_err::{TransformMapErr, TransformMapErrNewTransform}; +use crate::transform_map_init_err::TransformMapInitErr; use crate::Service; /// An asynchronous function for transforming service call result. @@ -85,6 +86,16 @@ pub trait NewTransform { { TransformMapErrNewTransform::new(self, f) } + + /// Map this service's factory init error to a different error, + /// returning a new transform service factory. + fn map_init_err(self, f: F) -> TransformMapInitErr + where + Self: Sized, + F: Fn(Self::InitError) -> E, + { + TransformMapInitErr::new(self, f) + } } impl<'a, T, S> Transform for &'a mut T diff --git a/actix-service/src/transform_map_init_err.rs b/actix-service/src/transform_map_init_err.rs new file mode 100644 index 00000000..bddd68ff --- /dev/null +++ b/actix-service/src/transform_map_init_err.rs @@ -0,0 +1,94 @@ +use std::marker::PhantomData; + +use futures::{Future, Poll}; + +use super::NewTransform; + +/// NewTransform for the `map_init_err` combinator, changing the type of a new +/// transform's error. +/// +/// This is created by the `NewTransform::map_init_err` method. +pub struct TransformMapInitErr { + t: T, + f: F, + e: PhantomData<(S, C, E)>, +} + +impl TransformMapInitErr { + /// Create new `MapInitErr` new transform instance + pub fn new(t: T, f: F) -> Self + where + T: NewTransform, + F: Fn(T::InitError) -> E, + { + Self { + t, + f, + e: PhantomData, + } + } +} + +impl Clone for TransformMapInitErr +where + T: Clone, + F: Clone, +{ + fn clone(&self) -> Self { + Self { + t: self.t.clone(), + f: self.f.clone(), + e: PhantomData, + } + } +} + +impl NewTransform for TransformMapInitErr +where + T: NewTransform, + F: Fn(T::InitError) -> E + Clone, +{ + type Request = T::Request; + type Response = T::Response; + type Error = T::Error; + type Transform = T::Transform; + + type InitError = E; + type Future = TransformMapInitErrFuture; + + fn new_transform(&self, cfg: &C) -> Self::Future { + TransformMapInitErrFuture::new(self.t.new_transform(cfg), self.f.clone()) + } +} + +pub struct TransformMapInitErrFuture +where + T: NewTransform, + F: Fn(T::InitError) -> E, +{ + fut: T::Future, + f: F, +} + +impl TransformMapInitErrFuture +where + T: NewTransform, + F: Fn(T::InitError) -> E, +{ + fn new(fut: T::Future, f: F) -> Self { + TransformMapInitErrFuture { f, fut } + } +} + +impl Future for TransformMapInitErrFuture +where + T: NewTransform, + F: Fn(T::InitError) -> E + Clone, +{ + type Item = T::Transform; + type Error = E; + + fn poll(&mut self) -> Poll { + self.fut.poll().map_err(|e| (self.f)(e)) + } +} diff --git a/actix-utils/src/inflight.rs b/actix-utils/src/inflight.rs index a8461ecb..32ddd54f 100644 --- a/actix-utils/src/inflight.rs +++ b/actix-utils/src/inflight.rs @@ -1,4 +1,4 @@ -use actix_service::{NewTransform, Service, Transform}; +use actix_service::{NewTransform, Service, Transform, Void}; use futures::future::{ok, FutureResult}; use futures::{Async, Future, Poll}; @@ -24,15 +24,15 @@ impl Default for InFlight { } } -impl NewTransform for InFlight { +impl NewTransform for InFlight { type Request = T::Request; type Response = T::Response; type Error = T::Error; - type InitError = (); + type InitError = Void; type Transform = InFlightService; type Future = FutureResult; - fn new_transform(&self) -> Self::Future { + fn new_transform(&self, _: &C) -> Self::Future { ok(InFlightService::new(self.max_inflight)) } } diff --git a/actix-utils/src/keepalive.rs b/actix-utils/src/keepalive.rs index d119773d..81305423 100644 --- a/actix-utils/src/keepalive.rs +++ b/actix-utils/src/keepalive.rs @@ -1,13 +1,12 @@ use std::marker::PhantomData; use std::time::{Duration, Instant}; -use actix_service::{NewService, Service}; +use actix_service::{NewService, Service, Void}; use futures::future::{ok, FutureResult}; use futures::{Async, Future, Poll}; use tokio_timer::Delay; use super::time::{LowResTime, LowResTimeService}; -use super::Never; pub struct KeepAlive { f: F, @@ -51,7 +50,7 @@ where type Request = R; type Response = R; type Error = E; - type InitError = Never; + type InitError = Void; type Service = KeepAliveService; type Future = FutureResult; diff --git a/actix-utils/src/order.rs b/actix-utils/src/order.rs index 0cec1b84..293a022b 100644 --- a/actix-utils/src/order.rs +++ b/actix-utils/src/order.rs @@ -3,7 +3,7 @@ use std::fmt; use std::marker::PhantomData; use std::rc::Rc; -use actix_service::{NewTransform, Service, Transform}; +use actix_service::{NewTransform, Service, Transform, Void}; use futures::future::{ok, FutureResult}; use futures::task::AtomicTask; use futures::unsync::oneshot; @@ -85,7 +85,7 @@ where } } -impl NewTransform for InOrder +impl NewTransform for InOrder where S: Service, S::Response: 'static, @@ -95,11 +95,11 @@ where type Request = S::Request; type Response = S::Response; type Error = InOrderError; - type InitError = (); + type InitError = Void; type Transform = InOrderService; type Future = FutureResult; - fn new_transform(&self) -> Self::Future { + fn new_transform(&self, _: &C) -> Self::Future { ok(InOrderService::new()) } } diff --git a/actix-utils/src/time.rs b/actix-utils/src/time.rs index 06d853bc..c30052d0 100644 --- a/actix-utils/src/time.rs +++ b/actix-utils/src/time.rs @@ -1,12 +1,11 @@ use std::time::{self, Duration, Instant}; -use actix_service::{NewService, Service}; +use actix_service::{NewService, Service, Void}; use futures::future::{ok, FutureResult}; use futures::{Async, Future, Poll}; use tokio_timer::sleep; use super::cell::Cell; -use super::Never; #[derive(Clone, Debug)] pub struct LowResTime(Cell); @@ -45,8 +44,8 @@ impl Default for LowResTime { impl NewService<()> for LowResTime { type Request = (); type Response = Instant; - type Error = Never; - type InitError = Never; + type Error = Void; + type InitError = Void; type Service = LowResTimeService; type Future = FutureResult; @@ -92,7 +91,7 @@ impl LowResTimeService { impl Service for LowResTimeService { type Request = (); type Response = Instant; - type Error = Never; + type Error = Void; type Future = FutureResult; fn poll_ready(&mut self) -> Poll<(), Self::Error> { diff --git a/actix-utils/src/timeout.rs b/actix-utils/src/timeout.rs index 28971c31..5c452854 100644 --- a/actix-utils/src/timeout.rs +++ b/actix-utils/src/timeout.rs @@ -80,7 +80,7 @@ impl Clone for Timeout { } } -impl NewTransform for Timeout +impl NewTransform for Timeout where S: Service, { @@ -91,7 +91,7 @@ where type Transform = TimeoutService; type Future = FutureResult; - fn new_transform(&self) -> Self::Future { + fn new_transform(&self, _: &C) -> Self::Future { ok(TimeoutService { timeout: self.timeout, })