From f0776fca94902d92e789fd72d38fbeb16eb0be8f Mon Sep 17 00:00:00 2001 From: Nikolay Kim Date: Sun, 12 May 2019 06:03:50 -0700 Subject: [PATCH] Use associated type for NewService config --- Cargo.toml | 6 + actix-connect/CHANGES.md | 7 + actix-connect/src/connector.rs | 1 + actix-connect/src/lib.rs | 13 +- actix-connect/src/resolver.rs | 1 + actix-connect/src/ssl/openssl.rs | 3 +- actix-connect/tests/test_connect.rs | 10 +- actix-server/CHANGES.md | 11 + actix-server/src/config.rs | 11 +- actix-server/src/services.rs | 4 +- actix-server/src/ssl/mod.rs | 1 + actix-server/src/ssl/nativetls.rs | 4 +- actix-server/src/ssl/openssl.rs | 3 +- actix-server/src/ssl/rustls.rs | 4 +- actix-server/tests/test_server.rs | 10 +- actix-service/CHANGES.md | 15 ++ actix-service/Cargo.toml | 3 +- actix-service/src/and_then.rs | 66 +++--- actix-service/src/and_then_apply.rs | 36 ++-- actix-service/src/and_then_apply_fn.rs | 42 ++-- actix-service/src/apply.rs | 52 +++-- actix-service/src/apply_cfg.rs | 164 +++++++-------- actix-service/src/blank.rs | 5 +- actix-service/src/boxed.rs | 23 ++- actix-service/src/cell.rs | 4 + actix-service/src/fn_service.rs | 207 ++++++++++--------- actix-service/src/fn_transform.rs | 5 +- actix-service/src/from_err.rs | 29 +-- actix-service/src/lib.rs | 156 ++++++-------- actix-service/src/map.rs | 33 +-- actix-service/src/map_config.rs | 112 ++++++++++ actix-service/src/map_err.rs | 37 ++-- actix-service/src/map_init_err.rs | 33 +-- actix-service/src/then.rs | 48 ++--- actix-service/src/transform.rs | 36 ++-- actix-test-server/src/lib.rs | 4 +- actix-utils/CHANGES.md | 13 ++ actix-utils/Cargo.toml | 3 +- actix-utils/src/either.rs | 149 +++++++------- actix-utils/src/framed.rs | 269 ++++--------------------- actix-utils/src/inflight.rs | 6 +- actix-utils/src/keepalive.rs | 8 +- actix-utils/src/order.rs | 5 +- actix-utils/src/stream.rs | 150 +------------- actix-utils/src/time.rs | 12 +- examples/basic.rs | 6 +- 46 files changed, 810 insertions(+), 1010 deletions(-) create mode 100644 actix-service/src/map_config.rs diff --git a/Cargo.toml b/Cargo.toml index 3ff71a3d..51d182d3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,3 +37,9 @@ futures = "0.1.25" openssl = "0.10" tokio-tcp = "0.1" tokio-openssl = "0.3" + +[patch.crates-io] +actix-service = { path = "actix-service" } +actix-utils = { path = "actix-utils" } +actix-server = { path = "actix-server" } +actix-connect = { path = "actix-connect" } diff --git a/actix-connect/CHANGES.md b/actix-connect/CHANGES.md index ccb895e2..9fa67e22 100644 --- a/actix-connect/CHANGES.md +++ b/actix-connect/CHANGES.md @@ -1,5 +1,12 @@ # Changes +## [0.2.0] - 2019-05-11 + +### Changed + +* Upgrade to actix-service 0.4 + + ## [0.1.5] - 2019-04-19 ### Added diff --git a/actix-connect/src/connector.rs b/actix-connect/src/connector.rs index 7c5c178b..9bae8a7f 100644 --- a/actix-connect/src/connector.rs +++ b/actix-connect/src/connector.rs @@ -30,6 +30,7 @@ impl NewService for TcpConnectorFactory { type Request = Connect; type Response = Connection; type Error = ConnectError; + type Config = (); type Service = TcpConnector; type InitError = (); type Future = FutureResult; diff --git a/actix-connect/src/lib.rs b/actix-connect/src/lib.rs index 8a1085f1..f00c6038 100644 --- a/actix-connect/src/lib.rs +++ b/actix-connect/src/lib.rs @@ -31,17 +31,6 @@ pub use self::resolver::{Resolver, ResolverFactory}; use actix_service::{NewService, Service, ServiceExt}; use tokio_tcp::TcpStream; -#[doc(hidden)] -#[deprecated(since = "0.1.2", note = "please use `actix_connect::TcpConnector`")] -pub type Connector = TcpConnector; - -#[doc(hidden)] -#[deprecated( - since = "0.1.2", - note = "please use `actix_connect::TcpConnectorFactory`" -)] -pub type ConnectorFactory = TcpConnectorFactory; - pub fn start_resolver(cfg: ResolverConfig, opts: ResolverOpts) -> AsyncResolver { let (resolver, bg) = AsyncResolver::new(cfg, opts); tokio_current_thread::spawn(bg); @@ -90,6 +79,7 @@ pub fn new_connector( pub fn new_connector_factory( resolver: AsyncResolver, ) -> impl NewService< + Config = (), Request = Connect, Response = Connection, Error = ConnectError, @@ -107,6 +97,7 @@ pub fn default_connector( /// Create connector service factory with default parameters pub fn default_connector_factory() -> impl NewService< + Config = (), Request = Connect, Response = Connection, Error = ConnectError, diff --git a/actix-connect/src/resolver.rs b/actix-connect/src/resolver.rs index aba97ad9..a5adc4ae 100644 --- a/actix-connect/src/resolver.rs +++ b/actix-connect/src/resolver.rs @@ -50,6 +50,7 @@ impl NewService for ResolverFactory { type Request = Connect; type Response = Connect; type Error = ConnectError; + type Config = (); type Service = Resolver; type InitError = (); type Future = FutureResult; diff --git a/actix-connect/src/ssl/openssl.rs b/actix-connect/src/ssl/openssl.rs index 15ebf2dc..89504db3 100644 --- a/actix-connect/src/ssl/openssl.rs +++ b/actix-connect/src/ssl/openssl.rs @@ -52,13 +52,14 @@ impl Clone for OpensslConnector { } } -impl NewService<()> for OpensslConnector +impl NewService for OpensslConnector where U: AsyncRead + AsyncWrite + fmt::Debug, { type Request = Connection; type Response = Connection>; type Error = HandshakeError; + type Config = (); type Service = OpensslConnectorService; type InitError = (); type Future = FutureResult; diff --git a/actix-connect/tests/test_connect.rs b/actix-connect/tests/test_connect.rs index 943919f8..481457d3 100644 --- a/actix-connect/tests/test_connect.rs +++ b/actix-connect/tests/test_connect.rs @@ -1,6 +1,6 @@ use actix_codec::{BytesCodec, Framed}; use actix_server_config::Io; -use actix_service::{fn_service, NewService, Service}; +use actix_service::{service_fn, NewService, Service}; use actix_test_server::TestServer; use bytes::Bytes; use futures::{future::lazy, Future, Sink}; @@ -13,7 +13,7 @@ use actix_connect::{default_connector, Connect}; #[test] fn test_string() { let mut srv = TestServer::with(|| { - fn_service(|io: Io| { + service_fn(|io: Io| { Framed::new(io.into_parts().0, BytesCodec) .send(Bytes::from_static(b"test")) .then(|_| Ok::<_, ()>(())) @@ -29,7 +29,7 @@ fn test_string() { #[test] fn test_static_str() { let mut srv = TestServer::with(|| { - fn_service(|io: Io| { + service_fn(|io: Io| { Framed::new(io.into_parts().0, BytesCodec) .send(Bytes::from_static(b"test")) .then(|_| Ok::<_, ()>(())) @@ -63,7 +63,7 @@ fn test_static_str() { #[test] fn test_new_service() { let mut srv = TestServer::with(|| { - fn_service(|io: Io| { + service_fn(|io: Io| { Framed::new(io.into_parts().0, BytesCodec) .send(Bytes::from_static(b"test")) .then(|_| Ok::<_, ()>(())) @@ -95,7 +95,7 @@ fn test_new_service() { #[test] fn test_uri() { let mut srv = TestServer::with(|| { - fn_service(|io: Io| { + service_fn(|io: Io| { Framed::new(io.into_parts().0, BytesCodec) .send(Bytes::from_static(b"test")) .then(|_| Ok::<_, ()>(())) diff --git a/actix-server/CHANGES.md b/actix-server/CHANGES.md index 2a6814d0..d4b097ad 100644 --- a/actix-server/CHANGES.md +++ b/actix-server/CHANGES.md @@ -1,5 +1,16 @@ # Changes +## [0.5.0] - 2019-05-11 + +### Added + +* Add `Debug` impl for `SslError` + +### Changed + +* Upgrade to actix-service 0.4 + + ## [0.4.3] - 2019-04-16 ### Added diff --git a/actix-server/src/config.rs b/actix-server/src/config.rs index a861ad9b..1bb2d2ac 100644 --- a/actix-server/src/config.rs +++ b/actix-server/src/config.rs @@ -207,8 +207,8 @@ impl ServiceRuntime { /// *ServiceConfig::bind()* or *ServiceConfig::listen()* methods. pub fn service(&mut self, name: &str, service: F) where - F: IntoNewService, - T: NewService> + 'static, + F: IntoNewService, + T: NewService> + 'static, T::Future: 'static, T::Service: 'static, T::InitError: fmt::Debug, @@ -237,11 +237,11 @@ impl ServiceRuntime { type BoxedNewService = Box< NewService< - ServerConfig, Request = (Option, ServerMessage), Response = (), Error = (), InitError = (), + Config = ServerConfig, Service = BoxedServerService, Future = Box>, >, @@ -251,9 +251,9 @@ struct ServiceFactory { inner: T, } -impl NewService for ServiceFactory +impl NewService for ServiceFactory where - T: NewService>, + T: NewService>, T::Future: 'static, T::Service: 'static, T::Error: 'static, @@ -263,6 +263,7 @@ where type Response = (); type Error = (); type InitError = (); + type Config = ServerConfig; type Service = BoxedServerService; type Future = Box>; diff --git a/actix-server/src/services.rs b/actix-server/src/services.rs index 91685b5d..afdc06ee 100644 --- a/actix-server/src/services.rs +++ b/actix-server/src/services.rs @@ -24,7 +24,7 @@ pub(crate) enum ServerMessage { } pub trait ServiceFactory: Send + Clone + 'static { - type NewService: NewService>; + type NewService: NewService>; fn create(&self) -> Self::NewService; } @@ -169,7 +169,7 @@ impl InternalServiceFactory for Box { impl ServiceFactory for F where F: Fn() -> T + Send + Clone + 'static, - T: NewService>, + T: NewService>, { type NewService = T; diff --git a/actix-server/src/ssl/mod.rs b/actix-server/src/ssl/mod.rs index 136da81f..6ce1222f 100644 --- a/actix-server/src/ssl/mod.rs +++ b/actix-server/src/ssl/mod.rs @@ -35,6 +35,7 @@ thread_local! { } /// Ssl error combinded with service error. +#[derive(Debug)] pub enum SslError { Ssl(E1), Service(E2), diff --git a/actix-server/src/ssl/nativetls.rs b/actix-server/src/ssl/nativetls.rs index 62b8f4c7..3a6859fe 100644 --- a/actix-server/src/ssl/nativetls.rs +++ b/actix-server/src/ssl/nativetls.rs @@ -37,10 +37,12 @@ impl Clone for NativeTlsAcceptor { } } -impl NewService for NativeTlsAcceptor { +impl NewService for NativeTlsAcceptor { type Request = Io; type Response = Io, P>; type Error = Error; + + type Config = ServerConfig; type Service = NativeTlsAcceptorService; type InitError = (); type Future = FutureResult; diff --git a/actix-server/src/ssl/openssl.rs b/actix-server/src/ssl/openssl.rs index dc460537..9a9b2120 100644 --- a/actix-server/src/ssl/openssl.rs +++ b/actix-server/src/ssl/openssl.rs @@ -37,10 +37,11 @@ impl Clone for OpensslAcceptor { } } -impl NewService for OpensslAcceptor { +impl NewService for OpensslAcceptor { type Request = Io; type Response = Io, P>; type Error = HandshakeError; + type Config = ServerConfig; type Service = OpensslAcceptorService; type InitError = (); type Future = FutureResult; diff --git a/actix-server/src/ssl/rustls.rs b/actix-server/src/ssl/rustls.rs index 11bca355..151bbbd6 100644 --- a/actix-server/src/ssl/rustls.rs +++ b/actix-server/src/ssl/rustls.rs @@ -39,10 +39,12 @@ impl Clone for RustlsAcceptor { } } -impl NewService for RustlsAcceptor { +impl NewService for RustlsAcceptor { type Request = Io; type Response = Io, P>; type Error = io::Error; + + type Config = SrvConfig; type Service = RustlsAcceptorService; type InitError = (); type Future = FutureResult; diff --git a/actix-server/tests/test_server.rs b/actix-server/tests/test_server.rs index 6afb8ca6..de7f7b09 100644 --- a/actix-server/tests/test_server.rs +++ b/actix-server/tests/test_server.rs @@ -4,7 +4,7 @@ use std::{net, thread, time}; use actix_codec::{BytesCodec, Framed}; use actix_server::{Io, Server, ServerConfig}; -use actix_service::{fn_cfg_factory, fn_service, IntoService}; +use actix_service::{new_service_cfg, service_fn, IntoService}; use bytes::Bytes; use futures::{Future, Sink}; use net2::TcpBuilder; @@ -28,7 +28,7 @@ fn test_bind() { let sys = actix_rt::System::new("test"); let srv = Server::build() .bind("test", addr, move || { - fn_cfg_factory(move |cfg: &ServerConfig| { + new_service_cfg(move |cfg: &ServerConfig| { assert_eq!(cfg.local_addr(), addr); Ok::<_, ()>((|_| Ok::<_, ()>(())).into_service()) }) @@ -54,7 +54,7 @@ fn test_bind_no_config() { let h = thread::spawn(move || { let sys = actix_rt::System::new("test"); let srv = Server::build() - .bind("test", addr, move || fn_service(|_| Ok::<_, ()>(()))) + .bind("test", addr, move || service_fn(|_| Ok::<_, ()>(()))) .unwrap() .start(); let _ = tx.send((srv, actix_rt::System::current())); @@ -76,7 +76,7 @@ fn test_listen() { let lst = net::TcpListener::bind(addr).unwrap(); let srv = Server::build() .listen("test", lst, move || { - fn_cfg_factory(move |cfg: &ServerConfig| { + new_service_cfg(move |cfg: &ServerConfig| { assert_eq!(cfg.local_addr(), addr); Ok::<_, ()>((|_| Ok::<_, ()>(())).into_service()) }) @@ -105,7 +105,7 @@ fn test_start() { let srv = Server::build() .backlog(100) .bind("test", addr, move || { - fn_cfg_factory(move |cfg: &ServerConfig| { + new_service_cfg(move |cfg: &ServerConfig| { assert_eq!(cfg.local_addr(), addr); Ok::<_, ()>( (|io: Io| { diff --git a/actix-service/CHANGES.md b/actix-service/CHANGES.md index 034585c0..3e617515 100644 --- a/actix-service/CHANGES.md +++ b/actix-service/CHANGES.md @@ -1,5 +1,20 @@ # Changes +## [0.4.0] - 2019-05-11 + +### Changed + +* Use associated type for `NewService` config + +* Change `apply_cfg` function + +* Renamed helper functions + +### Added + +* Add `NewService::map_config` and `NewService::unit_config` combinators + + ## [0.3.6] - 2019-04-07 ### Changed diff --git a/actix-service/Cargo.toml b/actix-service/Cargo.toml index bf835bce..f0186f44 100644 --- a/actix-service/Cargo.toml +++ b/actix-service/Cargo.toml @@ -23,8 +23,7 @@ name = "actix_service" path = "src/lib.rs" [dependencies] -futures = "0.1.24" -void = "1.0.2" +futures = "0.1.25" [dev-dependencies] actix-rt = "0.2" \ No newline at end of file diff --git a/actix-service/src/and_then.rs b/actix-service/src/and_then.rs index 38a4a5b5..208c7b09 100644 --- a/actix-service/src/and_then.rs +++ b/actix-service/src/and_then.rs @@ -1,5 +1,3 @@ -use std::marker::PhantomData; - use futures::{Async, Future, Poll}; use super::{IntoNewService, NewService, Service}; @@ -111,67 +109,75 @@ where } /// `AndThenNewService` new service combinator -pub struct AndThenNewService +pub struct AndThenNewService where - A: NewService, - B: NewService, + A: NewService, + B: NewService, { a: A, b: B, - _t: PhantomData, } -impl AndThenNewService +impl AndThenNewService where - A: NewService, - B: NewService, + A: NewService, + B: NewService< + Config = A::Config, + Request = A::Response, + Error = A::Error, + InitError = A::InitError, + >, { /// Create new `AndThen` combinator - pub fn new>(a: A, f: F) -> Self { + pub fn new>(a: A, f: F) -> Self { Self { a, b: f.into_new_service(), - _t: PhantomData, } } } -impl NewService for AndThenNewService +impl NewService for AndThenNewService where - A: NewService, - B: NewService, + A: NewService, + B: NewService< + Config = A::Config, + Request = A::Response, + Error = A::Error, + InitError = A::InitError, + >, { type Request = A::Request; type Response = B::Response; type Error = A::Error; + + type Config = A::Config; type Service = AndThen; - type InitError = A::InitError; - type Future = AndThenNewServiceFuture; + type Future = AndThenNewServiceFuture; - fn new_service(&self, cfg: &C) -> Self::Future { + fn new_service(&self, cfg: &A::Config) -> Self::Future { AndThenNewServiceFuture::new(self.a.new_service(cfg), self.b.new_service(cfg)) } } -impl Clone for AndThenNewService +impl Clone for AndThenNewService where - A: NewService + Clone, - B: NewService + Clone, + A: NewService + Clone, + B: NewService + Clone, { fn clone(&self) -> Self { Self { a: self.a.clone(), b: self.b.clone(), - _t: PhantomData, } } } -pub struct AndThenNewServiceFuture +pub struct AndThenNewServiceFuture where - A: NewService, - B: NewService, + A: NewService, + B: NewService, { fut_b: B::Future, fut_a: A::Future, @@ -179,10 +185,10 @@ where b: Option, } -impl AndThenNewServiceFuture +impl AndThenNewServiceFuture where - A: NewService, - B: NewService, + A: NewService, + B: NewService, { fn new(fut_a: A::Future, fut_b: B::Future) -> Self { AndThenNewServiceFuture { @@ -194,10 +200,10 @@ where } } -impl Future for AndThenNewServiceFuture +impl Future for AndThenNewServiceFuture where - A: NewService, - B: NewService, + A: NewService, + B: NewService, { type Item = AndThen; type Error = A::InitError; diff --git a/actix-service/src/and_then_apply.rs b/actix-service/src/and_then_apply.rs index 7ea0dab3..a8ce6991 100644 --- a/actix-service/src/and_then_apply.rs +++ b/actix-service/src/and_then_apply.rs @@ -7,17 +7,16 @@ use crate::from_err::FromErr; use crate::{NewService, Transform}; /// `Apply` new service combinator -pub struct AndThenTransform { +pub struct AndThenTransform { a: A, b: B, t: Rc, - _t: std::marker::PhantomData, } -impl AndThenTransform +impl AndThenTransform where - A: NewService, - B: NewService, + A: NewService, + B: NewService, T: Transform, T::Error: From, { @@ -27,12 +26,11 @@ where a, b, t: Rc::new(t), - _t: std::marker::PhantomData, } } } -impl Clone for AndThenTransform +impl Clone for AndThenTransform where A: Clone, B: Clone, @@ -42,15 +40,14 @@ where a: self.a.clone(), b: self.b.clone(), t: self.t.clone(), - _t: std::marker::PhantomData, } } } -impl NewService for AndThenTransform +impl NewService for AndThenTransform where - A: NewService, - B: NewService, + A: NewService, + B: NewService, T: Transform, T::Error: From, { @@ -58,11 +55,12 @@ where type Response = T::Response; type Error = T::Error; + type Config = A::Config; type InitError = T::InitError; type Service = AndThen, T::Transform>; - type Future = AndThenTransformFuture; + type Future = AndThenTransformFuture; - fn new_service(&self, cfg: &C) -> Self::Future { + fn new_service(&self, cfg: &A::Config) -> Self::Future { AndThenTransformFuture { a: None, t: None, @@ -74,10 +72,10 @@ where } } -pub struct AndThenTransformFuture +pub struct AndThenTransformFuture where - A: NewService, - B: NewService, + A: NewService, + B: NewService, T: Transform, T::Error: From, { @@ -89,10 +87,10 @@ where t_cell: Rc, } -impl Future for AndThenTransformFuture +impl Future for AndThenTransformFuture where - A: NewService, - B: NewService, + A: NewService, + B: NewService, T: Transform, T::Error: From, { diff --git a/actix-service/src/and_then_apply_fn.rs b/actix-service/src/and_then_apply_fn.rs index 423a8eec..5fd846b7 100644 --- a/actix-service/src/and_then_apply_fn.rs +++ b/actix-service/src/and_then_apply_fn.rs @@ -133,27 +133,23 @@ where } /// `ApplyNewService` new service combinator -pub struct AndThenApplyNewService { +pub struct AndThenApplyNewService { a: A, b: B, f: Cell, - r: PhantomData<(Out, Cfg)>, + r: PhantomData, } -impl AndThenApplyNewService +impl AndThenApplyNewService where - A: NewService, - B: NewService, + A: NewService, + B: NewService, F: FnMut(A::Response, &mut B::Service) -> Out, Out: IntoFuture, Out::Error: Into, { /// Create new `ApplyNewService` new service instance - pub fn new, B1: IntoNewService>( - a: A1, - b: B1, - f: F, - ) -> Self { + pub fn new, B1: IntoNewService>(a: A1, b: B1, f: F) -> Self { Self { f: Cell::new(f), a: a.into_new_service(), @@ -163,7 +159,7 @@ where } } -impl Clone for AndThenApplyNewService +impl Clone for AndThenApplyNewService where A: Clone, B: Clone, @@ -178,10 +174,10 @@ where } } -impl NewService for AndThenApplyNewService +impl NewService for AndThenApplyNewService where - A: NewService, - B: NewService, + A: NewService, + B: NewService, F: FnMut(A::Response, &mut B::Service) -> Out, Out: IntoFuture, Out::Error: Into, @@ -190,11 +186,11 @@ where type Response = Out::Item; type Error = A::Error; type Service = AndThenApply; - + type Config = A::Config; type InitError = A::InitError; - type Future = AndThenApplyNewServiceFuture; + type Future = AndThenApplyNewServiceFuture; - fn new_service(&self, cfg: &Cfg) -> Self::Future { + fn new_service(&self, cfg: &A::Config) -> Self::Future { AndThenApplyNewServiceFuture { a: None, b: None, @@ -205,10 +201,10 @@ where } } -pub struct AndThenApplyNewServiceFuture +pub struct AndThenApplyNewServiceFuture where - A: NewService, - B: NewService, + A: NewService, + B: NewService, F: FnMut(A::Response, &mut B::Service) -> Out, Out: IntoFuture, Out::Error: Into, @@ -220,10 +216,10 @@ where b: Option, } -impl Future for AndThenApplyNewServiceFuture +impl Future for AndThenApplyNewServiceFuture where - A: NewService, - B: NewService, + A: NewService, + B: NewService, F: FnMut(A::Response, &mut B::Service) -> Out, Out: IntoFuture, Out::Error: Into, diff --git a/actix-service/src/apply.rs b/actix-service/src/apply.rs index 9719e087..d5f84463 100644 --- a/actix-service/src/apply.rs +++ b/actix-service/src/apply.rs @@ -16,17 +16,14 @@ where Apply::new(service.into_service(), f) } -/// Create fractory for `apply_fn` service. -pub fn apply_fn_factory( - service: U, - f: F, -) -> ApplyNewService +/// Create factory for `apply` service. +pub fn new_apply_fn(service: U, f: F) -> ApplyNewService where - T: NewService, + T: NewService, F: FnMut(In, &mut T::Service) -> Out + Clone, Out: IntoFuture, Out::Error: From, - U: IntoNewService, + U: IntoNewService, { ApplyNewService::new(service.into_new_service(), f) } @@ -50,7 +47,7 @@ where Out::Error: From, { /// Create new `Apply` combinator - pub fn new>(service: I, f: F) -> Self { + pub(crate) fn new>(service: I, f: F) -> Self { Self { service: service.into_service(), f, @@ -95,24 +92,24 @@ where } /// `ApplyNewService` new service combinator -pub struct ApplyNewService +pub struct ApplyNewService where - T: NewService, + T: NewService, { service: T, f: F, - r: PhantomData<(In, Out, Cfg)>, + r: PhantomData<(In, Out)>, } -impl ApplyNewService +impl ApplyNewService where - T: NewService, + T: NewService, F: FnMut(In, &mut T::Service) -> Out + Clone, Out: IntoFuture, Out::Error: From, { /// Create new `ApplyNewService` new service instance - pub fn new>(service: F1, f: F) -> Self { + pub(crate) fn new>(service: F1, f: F) -> Self { Self { f, service: service.into_new_service(), @@ -121,9 +118,9 @@ where } } -impl Clone for ApplyNewService +impl Clone for ApplyNewService where - T: NewService + Clone, + T: NewService + Clone, F: FnMut(In, &mut T::Service) -> Out + Clone, Out: IntoFuture, { @@ -136,9 +133,9 @@ where } } -impl NewService for ApplyNewService +impl NewService for ApplyNewService where - T: NewService, + T: NewService, F: FnMut(In, &mut T::Service) -> Out + Clone, Out: IntoFuture, Out::Error: From, @@ -146,19 +143,20 @@ where type Request = In; type Response = Out::Item; type Error = Out::Error; + + type Config = T::Config; type Service = Apply; - type InitError = T::InitError; - type Future = ApplyNewServiceFuture; + type Future = ApplyNewServiceFuture; - fn new_service(&self, cfg: &Cfg) -> Self::Future { + fn new_service(&self, cfg: &T::Config) -> Self::Future { ApplyNewServiceFuture::new(self.service.new_service(cfg), self.f.clone()) } } -pub struct ApplyNewServiceFuture +pub struct ApplyNewServiceFuture where - T: NewService, + T: NewService, F: FnMut(In, &mut T::Service) -> Out + Clone, Out: IntoFuture, { @@ -167,9 +165,9 @@ where r: PhantomData<(In, Out)>, } -impl ApplyNewServiceFuture +impl ApplyNewServiceFuture where - T: NewService, + T: NewService, F: FnMut(In, &mut T::Service) -> Out + Clone, Out: IntoFuture, { @@ -182,9 +180,9 @@ where } } -impl Future for ApplyNewServiceFuture +impl Future for ApplyNewServiceFuture where - T: NewService, + T: NewService, F: FnMut(In, &mut T::Service) -> Out + Clone, Out: IntoFuture, Out::Error: From, diff --git a/actix-service/src/apply_cfg.rs b/actix-service/src/apply_cfg.rs index 66018b07..7924e716 100644 --- a/actix-service/src/apply_cfg.rs +++ b/actix-service/src/apply_cfg.rs @@ -1,112 +1,104 @@ use std::marker::PhantomData; -use crate::{IntoNewService, NewService}; +use futures::future::Future; +use futures::{try_ready, Async, IntoFuture, Poll}; -/// Create new ApplyConfig` service factory combinator -pub fn apply_cfg(f: F, service: U) -> ApplyConfig +use crate::cell::Cell; +use crate::{IntoService, NewService, Service}; + +/// Convert `Fn(&Config, &mut Service) -> Future` fn to a NewService +pub fn apply_cfg(srv: T, f: F) -> ApplyConfigService where - S: NewService, - F: Fn(&C1) -> C2, - U: IntoNewService, + F: FnMut(&C, &mut T) -> R, + T: Service, + R: IntoFuture, + R::Item: IntoService, + S: Service, { - ApplyConfig::new(service.into_new_service(), f) -} - -/// `ApplyConfig` service factory combinator -pub struct ApplyConfig { - s: S, - f: F, - r: PhantomData<(C1, C2)>, -} - -impl ApplyConfig -where - S: NewService, - F: Fn(&C1) -> C2, -{ - /// Create new ApplyConfig` service factory combinator - pub fn new>(a: U, f: F) -> Self { - Self { - f, - s: a.into_new_service(), - r: PhantomData, - } + ApplyConfigService { + f: Cell::new(f), + srv: Cell::new(srv.into_service()), + _t: PhantomData, } } -impl Clone for ApplyConfig +/// Convert `Fn(&Config) -> Future` fn to NewService +pub struct ApplyConfigService where - S: Clone, - F: Clone, + F: FnMut(&C, &mut T) -> R, + T: Service, + R: IntoFuture, + R::Item: IntoService, + S: Service, +{ + f: Cell, + srv: Cell, + _t: PhantomData<(C, R, S)>, +} + +impl Clone for ApplyConfigService +where + F: FnMut(&C, &mut T) -> R, + T: Service, + R: IntoFuture, + R::Item: IntoService, + S: Service, { fn clone(&self) -> Self { - Self { - s: self.s.clone(), + ApplyConfigService { f: self.f.clone(), - r: PhantomData, + srv: self.srv.clone(), + _t: PhantomData, } } } -impl NewService for ApplyConfig +impl NewService for ApplyConfigService where - S: NewService, - F: Fn(&C1) -> C2, + F: FnMut(&C, &mut T) -> R, + T: Service, + R: IntoFuture, + R::Item: IntoService, + S: Service, { + type Config = C; type Request = S::Request; type Response = S::Response; type Error = S::Error; - type Service = S::Service; + type Service = S; - type InitError = S::InitError; - type Future = S::Future; + type InitError = R::Error; + type Future = FnNewServiceConfigFut; - fn new_service(&self, cfg: &C1) -> Self::Future { - let cfg2 = (self.f)(cfg); - - self.s.new_service(&cfg2) - } -} - -#[cfg(test)] -mod tests { - use futures::future::{ok, FutureResult}; - use futures::{Async, Future, Poll}; - - use crate::{fn_cfg_factory, NewService, Service}; - - #[derive(Clone)] - struct Srv; - impl Service for Srv { - type Request = (); - type Response = (); - type Error = (); - type Future = FutureResult<(), ()>; - - fn poll_ready(&mut self) -> Poll<(), Self::Error> { - Ok(Async::Ready(())) - } - - fn call(&mut self, _: ()) -> Self::Future { - ok(()) - } - } - - #[test] - fn test_new_service() { - let new_srv = fn_cfg_factory(|_: &usize| Ok::<_, ()>(Srv)).apply_cfg( - fn_cfg_factory(|s: &String| { - assert_eq!(s, "test"); - Ok::<_, ()>(Srv) - }), - |cfg: &usize| { - assert_eq!(*cfg, 1); - "test".to_string() - }, - ); - - if let Async::Ready(mut srv) = new_srv.new_service(&1).poll().unwrap() { - assert!(srv.poll_ready().is_ok()); + fn new_service(&self, cfg: &C) -> Self::Future { + FnNewServiceConfigFut { + fut: unsafe { (self.f.get_mut_unsafe())(cfg, self.srv.get_mut_unsafe()) } + .into_future(), + _t: PhantomData, } } } + +pub struct FnNewServiceConfigFut +where + R: IntoFuture, + R::Item: IntoService, + S: Service, +{ + fut: R::Future, + _t: PhantomData<(S,)>, +} + +impl Future for FnNewServiceConfigFut +where + R: IntoFuture, + R::Item: IntoService, + S: Service, +{ + type Item = S; + type Error = R::Error; + + fn poll(&mut self) -> Poll { + Ok(Async::Ready(try_ready!(self.fut.poll()).into_service())) + } +} diff --git a/actix-service/src/blank.rs b/actix-service/src/blank.rs index ea10b424..d02f75f8 100644 --- a/actix-service/src/blank.rs +++ b/actix-service/src/blank.rs @@ -68,12 +68,13 @@ impl Default for BlankNewService { } } -impl NewService<()> for BlankNewService { +impl NewService for BlankNewService { type Request = R; type Response = R; type Error = E1; - type Service = Blank; + type Config = (); + type Service = Blank; type InitError = E2; type Future = FutureResult; diff --git a/actix-service/src/boxed.rs b/actix-service/src/boxed.rs index ab7fbecb..b9e14897 100644 --- a/actix-service/src/boxed.rs +++ b/actix-service/src/boxed.rs @@ -15,13 +15,14 @@ pub type BoxedService = Box< pub type BoxedServiceResponse = Either, Box>>; +pub struct BoxedNewService(Inner); + /// Create boxed new service -pub fn new_service( +pub fn new_service( service: T, -) -> BoxedNewService +) -> BoxedNewService where - C: 'static, - T: NewService + 'static, + T: NewService + 'static, T::Request: 'static, T::Response: 'static, T::Service: 'static, @@ -46,7 +47,7 @@ where type Inner = Box< NewService< - C, + Config = C, Request = Req, Response = Res, Error = Err, @@ -56,9 +57,7 @@ type Inner = Box< >, >; -pub struct BoxedNewService(Inner); - -impl NewService for BoxedNewService +impl NewService for BoxedNewService where Req: 'static, Res: 'static, @@ -69,6 +68,7 @@ where type Response = Res; type Error = Err; type InitError = InitErr; + type Config = C; type Service = BoxedService; type Future = Box>; @@ -77,18 +77,18 @@ where } } -struct NewServiceWrapper> { +struct NewServiceWrapper { service: T, _t: std::marker::PhantomData, } -impl NewService for NewServiceWrapper +impl NewService for NewServiceWrapper where Req: 'static, Res: 'static, Err: 'static, InitErr: 'static, - T: NewService, + T: NewService, T::Future: 'static, T::Service: 'static, ::Future: 'static, @@ -97,6 +97,7 @@ where type Response = Res; type Error = Err; type InitError = InitErr; + type Config = C; type Service = BoxedService; type Future = Box>; diff --git a/actix-service/src/cell.rs b/actix-service/src/cell.rs index 6136a716..33ecb97f 100644 --- a/actix-service/src/cell.rs +++ b/actix-service/src/cell.rs @@ -29,4 +29,8 @@ impl Cell { pub(crate) fn get_mut(&mut self) -> &mut T { unsafe { &mut *self.inner.as_ref().get() } } + + pub(crate) unsafe fn get_mut_unsafe(&self) -> &mut T { + &mut *self.inner.as_ref().get() + } } diff --git a/actix-service/src/fn_service.rs b/actix-service/src/fn_service.rs index c665b71f..8adcfd55 100644 --- a/actix-service/src/fn_service.rs +++ b/actix-service/src/fn_service.rs @@ -3,29 +3,30 @@ use std::marker::PhantomData; use futures::future::{ok, Future, FutureResult}; use futures::{try_ready, Async, IntoFuture, Poll}; -use crate::{IntoConfigurableNewService, IntoNewService, IntoService, NewService, Service}; +use crate::{IntoNewService, IntoService, NewService, Service}; -/// Create `NewService` for function that can act as Service -pub fn fn_service(f: F) -> FnNewService +/// Create `NewService` for function that can act as a Service +pub fn service_fn(f: F) -> NewServiceFn where F: FnMut(Req) -> Out + Clone, Out: IntoFuture, { - FnNewService::new(f) + NewServiceFn::new(f) } /// Create `NewService` for function that can produce services -pub fn fn_factory(f: F) -> FnNewServiceNoConfig +pub fn new_service_fn(f: F) -> FnNewServiceNoConfig where F: Fn() -> R, R: IntoFuture, + R::Item: IntoService, S: Service, { FnNewServiceNoConfig::new(f) } /// Create `NewService` for function that can produce services with configuration -pub fn fn_cfg_factory(f: F) -> FnNewServiceConfig +pub fn new_service_cfg(f: F) -> FnNewServiceConfig where F: Fn(&C) -> R, R: IntoFuture, @@ -35,39 +36,36 @@ where FnNewServiceConfig::new(f) } -pub struct FnService +pub struct ServiceFn where F: FnMut(Req) -> Out, Out: IntoFuture, { f: F, - _t: PhantomData<(Req,)>, + _t: PhantomData, } -impl FnService +impl ServiceFn where F: FnMut(Req) -> Out, Out: IntoFuture, { - pub fn new(f: F) -> Self { - FnService { f, _t: PhantomData } + pub(crate) fn new(f: F) -> Self { + ServiceFn { f, _t: PhantomData } } } -impl Clone for FnService +impl Clone for ServiceFn where F: FnMut(Req) -> Out + Clone, Out: IntoFuture, { fn clone(&self) -> Self { - FnService { - f: self.f.clone(), - _t: PhantomData, - } + ServiceFn::new(self.f.clone()) } } -impl Service for FnService +impl Service for ServiceFn where F: FnMut(Req) -> Out, Out: IntoFuture, @@ -86,17 +84,17 @@ where } } -impl IntoService> for F +impl IntoService> for F where - F: FnMut(Req) -> Out + 'static, + F: FnMut(Req) -> Out, Out: IntoFuture, { - fn into_service(self) -> FnService { - FnService::new(self) + fn into_service(self) -> ServiceFn { + ServiceFn::new(self) } } -pub struct FnNewService +pub struct NewServiceFn where F: FnMut(Req) -> Out, Out: IntoFuture, @@ -105,17 +103,27 @@ where _t: PhantomData<(Req, Cfg)>, } -impl FnNewService +impl NewServiceFn where F: FnMut(Req) -> Out + Clone, Out: IntoFuture, { - pub fn new(f: F) -> Self { - FnNewService { f, _t: PhantomData } + pub(crate) fn new(f: F) -> Self { + NewServiceFn { f, _t: PhantomData } } } -impl NewService for FnNewService +impl Clone for NewServiceFn +where + F: FnMut(Req) -> Out + Clone, + Out: IntoFuture, +{ + fn clone(&self) -> Self { + NewServiceFn::new(self.f.clone()) + } +} + +impl NewService for NewServiceFn where F: FnMut(Req) -> Out + Clone, Out: IntoFuture, @@ -123,95 +131,34 @@ where type Request = Req; type Response = Out::Item; type Error = Out::Error; - type Service = FnService; + type Config = Cfg; + type Service = ServiceFn; type InitError = (); type Future = FutureResult; fn new_service(&self, _: &Cfg) -> Self::Future { - ok(FnService::new(self.f.clone())) + ok(ServiceFn::new(self.f.clone())) } } -impl Clone for FnNewService +impl IntoService> for NewServiceFn where F: FnMut(Req) -> Out + Clone, Out: IntoFuture, { - fn clone(&self) -> Self { - Self::new(self.f.clone()) + fn into_service(self) -> ServiceFn { + ServiceFn::new(self.f.clone()) } } -impl IntoNewService, Cfg> for F +impl IntoNewService> for F where F: Fn(Req) -> Out + Clone, Out: IntoFuture, { - fn into_new_service(self) -> FnNewService { - FnNewService::new(self) - } -} - -/// Converter for `Fn() -> Future` fn -pub struct FnNewServiceNoConfig -where - F: Fn() -> R, - R: IntoFuture, - S: Service, -{ - f: F, -} - -impl FnNewServiceNoConfig -where - F: Fn() -> R, - R: IntoFuture, - S: Service, -{ - pub fn new(f: F) -> Self { - FnNewServiceNoConfig { f } - } -} - -impl NewService<()> for FnNewServiceNoConfig -where - F: Fn() -> R, - R: IntoFuture, - S: Service, -{ - type Request = S::Request; - type Response = S::Response; - type Error = S::Error; - type Service = S; - - type InitError = E; - type Future = R::Future; - - fn new_service(&self, _: &()) -> Self::Future { - (self.f)().into_future() - } -} - -impl Clone for FnNewServiceNoConfig -where - F: Fn() -> R + Clone, - R: IntoFuture, - S: Service, -{ - fn clone(&self) -> Self { - Self::new(self.f.clone()) - } -} - -impl IntoNewService, ()> for F -where - F: Fn() -> R, - R: IntoFuture, - S: Service, -{ - fn into_new_service(self) -> FnNewServiceNoConfig { - FnNewServiceNoConfig::new(self) + fn into_new_service(self) -> NewServiceFn { + NewServiceFn::new(self) } } @@ -239,7 +186,7 @@ where } } -impl NewService for FnNewServiceConfig +impl NewService for FnNewServiceConfig where F: Fn(&C) -> R, R: IntoFuture, @@ -249,8 +196,9 @@ where type Request = S::Request; type Response = S::Response; type Error = S::Error; - type Service = S; + type Config = C; + type Service = S; type InitError = E; type Future = FnNewServiceConfigFut; @@ -298,14 +246,65 @@ where } } -impl IntoConfigurableNewService, C> for F +/// Converter for `Fn() -> Future` fn +pub struct FnNewServiceNoConfig where - F: Fn(&C) -> R, - R: IntoFuture, - R::Item: IntoService, + F: Fn() -> R, + R: IntoFuture, S: Service, { - fn into_new_service(self) -> FnNewServiceConfig { - FnNewServiceConfig::new(self) + f: F, + _t: PhantomData, +} + +impl FnNewServiceNoConfig +where + F: Fn() -> R, + R: IntoFuture, + S: Service, +{ + pub fn new(f: F) -> Self { + FnNewServiceNoConfig { f, _t: PhantomData } + } +} + +impl NewService for FnNewServiceNoConfig +where + F: Fn() -> R, + R: IntoFuture, + S: Service, +{ + type Request = S::Request; + type Response = S::Response; + type Error = S::Error; + type Service = S; + type Config = C; + type InitError = E; + type Future = R::Future; + + fn new_service(&self, _: &C) -> Self::Future { + (self.f)().into_future() + } +} + +impl Clone for FnNewServiceNoConfig +where + F: Fn() -> R + Clone, + R: IntoFuture, + S: Service, +{ + fn clone(&self) -> Self { + Self::new(self.f.clone()) + } +} + +impl IntoNewService> for F +where + F: Fn() -> R, + R: IntoFuture, + S: Service, +{ + fn into_new_service(self) -> FnNewServiceNoConfig { + FnNewServiceNoConfig::new(self) } } diff --git a/actix-service/src/fn_transform.rs b/actix-service/src/fn_transform.rs index f7d708f7..2e4be2d5 100644 --- a/actix-service/src/fn_transform.rs +++ b/actix-service/src/fn_transform.rs @@ -3,10 +3,11 @@ use std::marker::PhantomData; use futures::future::{ok, FutureResult}; use futures::IntoFuture; -use crate::{Apply, IntoTransform, Service, Transform}; +use crate::apply::Apply; +use crate::{IntoTransform, Service, Transform}; /// Use function as transform service -pub fn fn_transform( +pub fn transform_fn( f: F, ) -> impl Transform where diff --git a/actix-service/src/from_err.rs b/actix-service/src/from_err.rs index 31ccb2d9..5d37d725 100644 --- a/actix-service/src/from_err.rs +++ b/actix-service/src/from_err.rs @@ -81,23 +81,23 @@ where /// service's error. /// /// This is created by the `NewServiceExt::from_err` method. -pub struct FromErrNewService { +pub struct FromErrNewService { a: A, - e: PhantomData<(E, C)>, + e: PhantomData, } -impl FromErrNewService { +impl FromErrNewService { /// Create new `FromErr` new service instance pub fn new(a: A) -> Self where - A: NewService, + A: NewService, E: From, { Self { a, e: PhantomData } } } -impl Clone for FromErrNewService +impl Clone for FromErrNewService where A: Clone, { @@ -109,20 +109,21 @@ where } } -impl NewService for FromErrNewService +impl NewService for FromErrNewService where - A: NewService, + A: NewService, E: From, { type Request = A::Request; type Response = A::Response; type Error = E; + + type Config = A::Config; type Service = FromErr; - type InitError = A::InitError; - type Future = FromErrNewServiceFuture; + type Future = FromErrNewServiceFuture; - fn new_service(&self, cfg: &C) -> Self::Future { + fn new_service(&self, cfg: &A::Config) -> Self::Future { FromErrNewServiceFuture { fut: self.a.new_service(cfg), e: PhantomData, @@ -130,18 +131,18 @@ where } } -pub struct FromErrNewServiceFuture +pub struct FromErrNewServiceFuture where - A: NewService, + A: NewService, E: From, { fut: A::Future, e: PhantomData, } -impl Future for FromErrNewServiceFuture +impl Future for FromErrNewServiceFuture where - A: NewService, + A: NewService, E: From, { type Item = FromErr; diff --git a/actix-service/src/lib.rs b/actix-service/src/lib.rs index 3b1e6e38..a973cc51 100644 --- a/actix-service/src/lib.rs +++ b/actix-service/src/lib.rs @@ -4,8 +4,6 @@ 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; @@ -18,40 +16,29 @@ mod fn_service; mod fn_transform; mod from_err; mod map; +mod map_config; mod map_err; mod map_init_err; mod then; mod transform; mod transform_err; -#[doc(hidden)] -#[deprecated(since = "0.3.4", note = "please use `apply_fn` instead")] -pub use self::apply::Apply; -#[doc(hidden)] -#[deprecated(since = "0.3.4", note = "please use `apply_fn_factory` instead")] -pub use self::apply::ApplyNewService; -#[doc(hidden)] -#[deprecated(since = "0.3.4", note = "please use `fn_transform` instead")] -pub use self::fn_transform::FnTransform; -#[doc(hidden)] -#[deprecated(since = "0.3.4", note = "please use `apply_transform` instead")] -pub use self::transform::ApplyTransform; - 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::{apply_fn, new_apply_fn, Apply, ApplyNewService}; 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::fn_service::{new_service_cfg, new_service_fn, service_fn, ServiceFn}; +pub use self::fn_transform::transform_fn; pub use self::from_err::{FromErr, FromErrNewService}; pub use self::map::{Map, MapNewService}; +pub use self::map_config::{MapConfig, MappedConfig, UnitConfig}; pub use self::map_err::{MapErr, MapErrNewService}; pub use self::map_init_err::MapInitErr; pub use self::then::{Then, ThenNewService}; pub use self::transform::{apply_transform, IntoTransform, Transform}; +use self::and_then_apply::AndThenTransform; +use self::and_then_apply_fn::{AndThenApply, AndThenApplyNewService}; + /// An asynchronous function from `Request` to a `Response`. pub trait Service { /// Requests handled by the service. @@ -195,7 +182,7 @@ impl ServiceExt for T where T: Service {} /// requests on that new TCP stream. /// /// `Config` is a service factory configuration type. -pub trait NewService { +pub trait NewService { /// Requests handled by the service. type Request; @@ -205,6 +192,9 @@ pub trait NewService { /// Errors produced by the service type Error; + /// Service factory configuration + type Config; + /// The `Service` value created by this factory type Service: Service< Request = Self::Request, @@ -219,37 +209,29 @@ pub trait NewService { type Future: Future; /// Create and return a new service value asynchronously. - fn new_service(&self, cfg: &Config) -> Self::Future; + fn new_service(&self, cfg: &Self::Config) -> Self::Future; /// Apply transform service to specified service and use it as a next service in /// chain. - fn apply( - self, - transform: T1, - service: B1, - ) -> AndThenTransform + fn apply(self, transform: T1, service: B1) -> AndThenTransform where Self: Sized, T: Transform, T::Error: From, T1: IntoTransform, - B: NewService, - B1: IntoNewService, + B: NewService, + B1: IntoNewService, { AndThenTransform::new(transform.into_transform(), self, service.into_new_service()) } /// Apply function to specified service and use it as a next service in /// chain. - fn apply_fn( - self, - service: I, - f: F, - ) -> AndThenApplyNewService + fn apply_fn(self, service: I, f: F) -> AndThenApplyNewService where Self: Sized, - B: NewService, - I: IntoNewService, + B: NewService, + I: IntoNewService, F: FnMut(Self::Response, &mut B::Service) -> Out, Out: IntoFuture, Out::Error: Into, @@ -257,34 +239,13 @@ pub trait NewService { AndThenApplyNewService::new(self, service, f) } - /// Map this service's config type to a different config, - /// and use for nested service - fn apply_cfg( - self, - service: U, - f: F, - ) -> AndThenNewService, Config> - where - Self: Sized, - F: Fn(&Config) -> C, - U: IntoNewService, - S: NewService< - C, - Request = Self::Response, - Error = Self::Error, - InitError = Self::InitError, - >, - { - self.and_then(ApplyConfig::new(service, f)) - } - /// Call another service after call to this one has resolved successfully. - fn and_then(self, new_service: F) -> AndThenNewService + fn and_then(self, new_service: F) -> AndThenNewService where Self: Sized, - F: IntoNewService, + F: IntoNewService, B: NewService< - Config, + Config = Self::Config, Request = Self::Response, Error = Self::Error, InitError = Self::InitError, @@ -299,7 +260,7 @@ pub trait NewService { /// /// Note that this function consumes the receiving new service and returns a /// wrapped version of it. - fn from_err(self) -> FromErrNewService + fn from_err(self) -> FromErrNewService where Self: Sized, E: From, @@ -313,12 +274,12 @@ pub trait NewService { /// /// Note that this function consumes the receiving future and returns a /// wrapped version of it. - fn then(self, new_service: F) -> ThenNewService + fn then(self, new_service: F) -> ThenNewService where Self: Sized, - F: IntoNewService, + F: IntoNewService, B: NewService< - Config, + Config = Self::Config, Request = Result, Error = Self::Error, InitError = Self::InitError, @@ -329,7 +290,7 @@ pub trait NewService { /// Map this service's output to a different type, returning a new service /// of the resulting type. - fn map(self, f: F) -> MapNewService + fn map(self, f: F) -> MapNewService where Self: Sized, F: FnMut(Self::Response) -> R, @@ -338,7 +299,7 @@ pub trait NewService { } /// Map this service's error to a different error, returning a new service. - fn map_err(self, f: F) -> MapErrNewService + fn map_err(self, f: F) -> MapErrNewService where Self: Sized, F: Fn(Self::Error) -> E + Clone, @@ -346,14 +307,31 @@ pub trait NewService { MapErrNewService::new(self, f) } - /// Map this service's init error to a different error, returning a new service. - fn map_init_err(self, f: F) -> MapInitErr + /// Map this factory's init error to a different error, returning a new service. + fn map_init_err(self, f: F) -> MapInitErr where Self: Sized, F: Fn(Self::InitError) -> E, { MapInitErr::new(self, f) } + + /// Map config to a different error, returning a new service. + fn map_config(self, f: F) -> MapConfig + where + Self: Sized, + F: Fn(&C) -> MappedConfig, + { + MapConfig::new(self, f) + } + + /// Replace config with unit + fn unit_config(self) -> UnitConfig + where + Self: NewService + Sized, + { + UnitConfig::new(self) + } } impl<'a, S> Service for &'a mut S @@ -410,34 +388,36 @@ where } } -impl NewService for Rc +impl NewService for Rc where - S: NewService, + S: NewService, { type Request = S::Request; type Response = S::Response; type Error = S::Error; + type Config = S::Config; type Service = S::Service; type InitError = S::InitError; type Future = S::Future; - fn new_service(&self, cfg: &C) -> S::Future { + fn new_service(&self, cfg: &S::Config) -> S::Future { self.as_ref().new_service(cfg) } } -impl NewService for Arc +impl NewService for Arc where - S: NewService, + S: NewService, { type Request = S::Request; type Response = S::Response; type Error = S::Error; + type Config = S::Config; type Service = S::Service; type InitError = S::InitError; type Future = S::Future; - fn new_service(&self, cfg: &C) -> S::Future { + fn new_service(&self, cfg: &S::Config) -> S::Future { self.as_ref().new_service(cfg) } } @@ -452,9 +432,9 @@ where } /// Trait for types that can be converted to a `NewService` -pub trait IntoNewService +pub trait IntoNewService where - T: NewService, + T: NewService, { /// Convert to an `NewService` fn into_new_service(self) -> T; @@ -469,27 +449,9 @@ where } } -impl IntoNewService for T +impl IntoNewService for T where - T: NewService, -{ - fn into_new_service(self) -> T { - self - } -} - -/// Trait for types that can be converted to a configurable `NewService` -pub trait IntoConfigurableNewService -where - T: NewService, -{ - /// Convert to an `NewService` - fn into_new_service(self) -> T; -} - -impl IntoConfigurableNewService for T -where - T: NewService, + T: NewService, { fn into_new_service(self) -> T { self diff --git a/actix-service/src/map.rs b/actix-service/src/map.rs index a98d14f5..ac3654b0 100644 --- a/actix-service/src/map.rs +++ b/actix-service/src/map.rs @@ -97,17 +97,17 @@ where } /// `MapNewService` new service combinator -pub struct MapNewService { +pub struct MapNewService { a: A, f: F, - r: PhantomData<(Res, Cfg)>, + r: PhantomData, } -impl MapNewService { +impl MapNewService { /// Create new `Map` new service instance pub fn new(a: A, f: F) -> Self where - A: NewService, + A: NewService, F: FnMut(A::Response) -> Res, { Self { @@ -118,7 +118,7 @@ impl MapNewService { } } -impl Clone for MapNewService +impl Clone for MapNewService where A: Clone, F: Clone, @@ -132,36 +132,37 @@ where } } -impl NewService for MapNewService +impl NewService for MapNewService where - A: NewService, + A: NewService, F: FnMut(A::Response) -> Res + Clone, { type Request = A::Request; type Response = Res; type Error = A::Error; + + type Config = A::Config; type Service = Map; - type InitError = A::InitError; - type Future = MapNewServiceFuture; + type Future = MapNewServiceFuture; - fn new_service(&self, cfg: &Cfg) -> Self::Future { + fn new_service(&self, cfg: &A::Config) -> Self::Future { MapNewServiceFuture::new(self.a.new_service(cfg), self.f.clone()) } } -pub struct MapNewServiceFuture +pub struct MapNewServiceFuture where - A: NewService, + A: NewService, F: FnMut(A::Response) -> Res, { fut: A::Future, f: Option, } -impl MapNewServiceFuture +impl MapNewServiceFuture where - A: NewService, + A: NewService, F: FnMut(A::Response) -> Res, { fn new(fut: A::Future, f: F) -> Self { @@ -169,9 +170,9 @@ where } } -impl Future for MapNewServiceFuture +impl Future for MapNewServiceFuture where - A: NewService, + A: NewService, F: FnMut(A::Response) -> Res, { type Item = Map; diff --git a/actix-service/src/map_config.rs b/actix-service/src/map_config.rs new file mode 100644 index 00000000..16830fc0 --- /dev/null +++ b/actix-service/src/map_config.rs @@ -0,0 +1,112 @@ +use std::marker::PhantomData; + +use super::NewService; + +pub enum MappedConfig<'a, T> { + Ref(&'a T), + Owned(T), +} + +/// `MapInitErr` service combinator +pub struct MapConfig { + a: A, + f: F, + e: PhantomData, +} + +impl MapConfig { + /// Create new `MapConfig` combinator + pub fn new(a: A, f: F) -> Self + where + A: NewService, + F: Fn(&C) -> MappedConfig, + { + Self { + a, + f, + e: PhantomData, + } + } +} + +impl Clone for MapConfig +where + A: Clone, + F: Clone, +{ + fn clone(&self) -> Self { + Self { + a: self.a.clone(), + f: self.f.clone(), + e: PhantomData, + } + } +} + +impl NewService for MapConfig +where + A: NewService, + F: Fn(&C) -> MappedConfig, +{ + type Request = A::Request; + type Response = A::Response; + type Error = A::Error; + + type Config = C; + type Service = A::Service; + type InitError = A::InitError; + type Future = A::Future; + + fn new_service(&self, cfg: &C) -> Self::Future { + match (self.f)(cfg) { + MappedConfig::Ref(cfg) => self.a.new_service(cfg), + MappedConfig::Owned(cfg) => self.a.new_service(&cfg), + } + } +} + +/// `MapInitErr` service combinator +pub struct UnitConfig { + a: A, + e: PhantomData, +} + +impl UnitConfig { + /// Create new `UnitConfig` combinator + pub fn new(a: A) -> Self + where + A: NewService, + { + Self { a, e: PhantomData } + } +} + +impl Clone for UnitConfig +where + A: Clone, +{ + fn clone(&self) -> Self { + Self { + a: self.a.clone(), + e: PhantomData, + } + } +} + +impl NewService for UnitConfig +where + A: NewService, +{ + type Request = A::Request; + type Response = A::Response; + type Error = A::Error; + + type Config = C; + type Service = A::Service; + type InitError = A::InitError; + type Future = A::Future; + + fn new_service(&self, _: &C) -> Self::Future { + self.a.new_service(&()) + } +} diff --git a/actix-service/src/map_err.rs b/actix-service/src/map_err.rs index 3cf18d7e..47ce11fc 100644 --- a/actix-service/src/map_err.rs +++ b/actix-service/src/map_err.rs @@ -98,19 +98,19 @@ where /// service's error. /// /// This is created by the `NewServiceExt::map_err` method. -pub struct MapErrNewService +pub struct MapErrNewService where - A: NewService, + A: NewService, F: Fn(A::Error) -> E + Clone, { a: A, f: F, - e: PhantomData<(E, C)>, + e: PhantomData, } -impl MapErrNewService +impl MapErrNewService where - A: NewService, + A: NewService, F: Fn(A::Error) -> E + Clone, { /// Create new `MapErr` new service instance @@ -123,9 +123,9 @@ where } } -impl Clone for MapErrNewService +impl Clone for MapErrNewService where - A: NewService + Clone, + A: NewService + Clone, F: Fn(A::Error) -> E + Clone, { fn clone(&self) -> Self { @@ -137,36 +137,37 @@ where } } -impl NewService for MapErrNewService +impl NewService for MapErrNewService where - A: NewService, + A: NewService, F: Fn(A::Error) -> E + Clone, { type Request = A::Request; type Response = A::Response; type Error = E; + + type Config = A::Config; type Service = MapErr; - type InitError = A::InitError; - type Future = MapErrNewServiceFuture; + type Future = MapErrNewServiceFuture; - fn new_service(&self, cfg: &C) -> Self::Future { + fn new_service(&self, cfg: &A::Config) -> Self::Future { MapErrNewServiceFuture::new(self.a.new_service(cfg), self.f.clone()) } } -pub struct MapErrNewServiceFuture +pub struct MapErrNewServiceFuture where - A: NewService, + A: NewService, F: Fn(A::Error) -> E, { fut: A::Future, f: F, } -impl MapErrNewServiceFuture +impl MapErrNewServiceFuture where - A: NewService, + A: NewService, F: Fn(A::Error) -> E, { fn new(fut: A::Future, f: F) -> Self { @@ -174,9 +175,9 @@ where } } -impl Future for MapErrNewServiceFuture +impl Future for MapErrNewServiceFuture where - A: NewService, + A: NewService, F: Fn(A::Error) -> E + Clone, { type Item = MapErr; diff --git a/actix-service/src/map_init_err.rs b/actix-service/src/map_init_err.rs index 094a4dbe..4866370a 100644 --- a/actix-service/src/map_init_err.rs +++ b/actix-service/src/map_init_err.rs @@ -5,17 +5,17 @@ use futures::{Future, Poll}; use super::NewService; /// `MapInitErr` service combinator -pub struct MapInitErr { +pub struct MapInitErr { a: A, f: F, - e: PhantomData<(E, C)>, + e: PhantomData, } -impl MapInitErr { +impl MapInitErr { /// Create new `MapInitErr` combinator pub fn new(a: A, f: F) -> Self where - A: NewService, + A: NewService, F: Fn(A::InitError) -> E, { Self { @@ -26,7 +26,7 @@ impl MapInitErr { } } -impl Clone for MapInitErr +impl Clone for MapInitErr where A: Clone, F: Clone, @@ -40,36 +40,37 @@ where } } -impl NewService for MapInitErr +impl NewService for MapInitErr where - A: NewService, + A: NewService, F: Fn(A::InitError) -> E + Clone, { type Request = A::Request; type Response = A::Response; type Error = A::Error; + + type Config = A::Config; type Service = A::Service; - type InitError = E; - type Future = MapInitErrFuture; + type Future = MapInitErrFuture; - fn new_service(&self, cfg: &C) -> Self::Future { + fn new_service(&self, cfg: &A::Config) -> Self::Future { MapInitErrFuture::new(self.a.new_service(cfg), self.f.clone()) } } -pub struct MapInitErrFuture +pub struct MapInitErrFuture where - A: NewService, + A: NewService, F: Fn(A::InitError) -> E, { f: F, fut: A::Future, } -impl MapInitErrFuture +impl MapInitErrFuture where - A: NewService, + A: NewService, F: Fn(A::InitError) -> E, { fn new(fut: A::Future, f: F) -> Self { @@ -77,9 +78,9 @@ where } } -impl Future for MapInitErrFuture +impl Future for MapInitErrFuture where - A: NewService, + A: NewService, F: Fn(A::InitError) -> E, { type Item = A::Service; diff --git a/actix-service/src/then.rs b/actix-service/src/then.rs index d30f1780..56fae3a1 100644 --- a/actix-service/src/then.rs +++ b/actix-service/src/then.rs @@ -1,5 +1,3 @@ -use std::marker::PhantomData; - use futures::{Async, Future, Poll}; use super::{IntoNewService, NewService, Service}; @@ -115,38 +113,36 @@ where } /// `ThenNewService` new service combinator -pub struct ThenNewService { +pub struct ThenNewService { a: A, b: B, - _t: PhantomData, } -impl ThenNewService { +impl ThenNewService { /// Create new `AndThen` combinator pub fn new(a: A, f: F) -> Self where - A: NewService, + A: NewService, B: NewService< - C, + Config = A::Config, Request = Result, Error = A::Error, InitError = A::InitError, >, - F: IntoNewService, + F: IntoNewService, { Self { a, b: f.into_new_service(), - _t: PhantomData, } } } -impl NewService for ThenNewService +impl NewService for ThenNewService where - A: NewService, + A: NewService, B: NewService< - C, + Config = A::Config, Request = Result, Error = A::Error, InitError = A::InitError, @@ -155,17 +151,18 @@ where type Request = A::Request; type Response = B::Response; type Error = A::Error; + + type Config = A::Config; type Service = Then; - type InitError = A::InitError; - type Future = ThenNewServiceFuture; + type Future = ThenNewServiceFuture; - fn new_service(&self, cfg: &C) -> Self::Future { + fn new_service(&self, cfg: &A::Config) -> Self::Future { ThenNewServiceFuture::new(self.a.new_service(cfg), self.b.new_service(cfg)) } } -impl Clone for ThenNewService +impl Clone for ThenNewService where A: Clone, B: Clone, @@ -174,16 +171,15 @@ where Self { a: self.a.clone(), b: self.b.clone(), - _t: PhantomData, } } } -pub struct ThenNewServiceFuture +pub struct ThenNewServiceFuture where - A: NewService, + A: NewService, B: NewService< - C, + Config = A::Config, Request = Result, Error = A::Error, InitError = A::InitError, @@ -195,11 +191,11 @@ where b: Option, } -impl ThenNewServiceFuture +impl ThenNewServiceFuture where - A: NewService, + A: NewService, B: NewService< - C, + Config = A::Config, Request = Result, Error = A::Error, InitError = A::InitError, @@ -215,11 +211,11 @@ where } } -impl Future for ThenNewServiceFuture +impl Future for ThenNewServiceFuture where - A: NewService, + A: NewService, B: NewService< - C, + Config = A::Config, Request = Result, Error = A::Error, InitError = A::InitError, diff --git a/actix-service/src/transform.rs b/actix-service/src/transform.rs index a57d1b40..2f82a292 100644 --- a/actix-service/src/transform.rs +++ b/actix-service/src/transform.rs @@ -133,11 +133,11 @@ where /// Apply transform to service factory. Function returns /// services factory that in initialization creates /// service and applies transform to this service. -pub fn apply_transform( +pub fn apply_transform( t: F, service: U, ) -> impl NewService< - C, + Config = S::Config, Request = T::Request, Response = T::Response, Error = T::Error, @@ -145,24 +145,23 @@ pub fn apply_transform( InitError = S::InitError, > + Clone where - S: NewService, + S: NewService, T: Transform, F: IntoTransform, - U: IntoNewService, + U: IntoNewService, { ApplyTransform::new(t.into_transform(), service.into_new_service()) } /// `Apply` transform to new service -pub struct ApplyTransform { +pub struct ApplyTransform { s: Rc, t: Rc, - _t: std::marker::PhantomData, } -impl ApplyTransform +impl ApplyTransform where - S: NewService, + S: NewService, T: Transform, { /// Create new `ApplyTransform` new service instance @@ -170,35 +169,34 @@ where Self { s: Rc::new(service), t: Rc::new(t.into_transform()), - _t: std::marker::PhantomData, } } } -impl Clone for ApplyTransform { +impl Clone for ApplyTransform { fn clone(&self) -> Self { ApplyTransform { s: self.s.clone(), t: self.t.clone(), - _t: std::marker::PhantomData, } } } -impl NewService for ApplyTransform +impl NewService for ApplyTransform where - S: NewService, + S: NewService, T: Transform, { type Request = T::Request; type Response = T::Response; type Error = T::Error; + type Config = S::Config; type Service = T::Transform; type InitError = T::InitError; - type Future = ApplyTransformFuture; + type Future = ApplyTransformFuture; - fn new_service(&self, cfg: &C) -> Self::Future { + fn new_service(&self, cfg: &S::Config) -> Self::Future { ApplyTransformFuture { t_cell: self.t.clone(), fut_a: self.s.new_service(cfg).into_future(), @@ -207,9 +205,9 @@ where } } -pub struct ApplyTransformFuture +pub struct ApplyTransformFuture where - S: NewService, + S: NewService, T: Transform, { fut_a: S::Future, @@ -217,9 +215,9 @@ where t_cell: Rc, } -impl Future for ApplyTransformFuture +impl Future for ApplyTransformFuture where - S: NewService, + S: NewService, T: Transform, { type Item = T::Transform; diff --git a/actix-test-server/src/lib.rs b/actix-test-server/src/lib.rs index dd7da733..7a3e0623 100644 --- a/actix-test-server/src/lib.rs +++ b/actix-test-server/src/lib.rs @@ -19,11 +19,11 @@ use tokio_tcp::TcpStream; /// # Examples /// /// ```rust -/// use actix_service::{fn_service, IntoNewService}; +/// use actix_service::{service_fn, IntoNewService}; /// use actix_test_server::TestServer; /// /// fn main() { -/// let srv = TestServer::with(|| fn_service( +/// let srv = TestServer::with(|| service_fn( /// |sock| { /// println!("New connection: {:?}", sock); /// Ok::<_, ()>(()) diff --git a/actix-utils/CHANGES.md b/actix-utils/CHANGES.md index ceaac115..a794c1e4 100644 --- a/actix-utils/CHANGES.md +++ b/actix-utils/CHANGES.md @@ -1,5 +1,18 @@ # Changes +## [0.4.0] - 2019-05-11 + +### Changed + +* Change `Either` to handle two nexted services + +* Upgrade actix-service 0.4 + +### Deleted + +* Framed related services + +* Stream related services ## [0.3.5] - 2019-04-04 diff --git a/actix-utils/Cargo.toml b/actix-utils/Cargo.toml index 55efd4f9..eef95667 100644 --- a/actix-utils/Cargo.toml +++ b/actix-utils/Cargo.toml @@ -21,7 +21,8 @@ path = "src/lib.rs" actix-service = "0.3.3" actix-codec = "0.1.1" bytes = "0.4" -futures = "0.1.24" +either = "1.5.2" +futures = "0.1.25" tokio-timer = "0.2.8" tokio-current-thread = "0.1.4" log = "0.4" diff --git a/actix-utils/src/either.rs b/actix-utils/src/either.rs index 885cd095..9078ae24 100644 --- a/actix-utils/src/either.rs +++ b/actix-utils/src/either.rs @@ -1,5 +1,5 @@ //! Contains `Either` service and related types and functions. -use actix_service::{NewService, Service}; +use actix_service::{IntoNewService, NewService, Service}; use futures::{future, try_ready, Async, Future, IntoFuture, Poll}; /// Combine two different service types into a single type. @@ -7,16 +7,16 @@ use futures::{future, try_ready, Async, Future, IntoFuture, Poll}; /// Both services must be of the same request, response, and error types. /// `EitherService` is useful for handling conditional branching in service /// middleware to different inner service types. -pub enum EitherService { - A(A), - B(B), +pub struct EitherService { + left: A, + right: B, } impl Clone for EitherService { fn clone(&self) -> Self { - match self { - EitherService::A(srv) => EitherService::A(srv.clone()), - EitherService::B(srv) => EitherService::B(srv.clone()), + EitherService { + left: self.left.clone(), + right: self.right.clone(), } } } @@ -24,129 +24,130 @@ impl Clone for EitherService { impl Service for EitherService where A: Service, - B: Service, + B: Service, { - type Request = A::Request; + type Request = either::Either; type Response = A::Response; type Error = A::Error; type Future = future::Either; fn poll_ready(&mut self) -> Poll<(), Self::Error> { - match self { - EitherService::A(ref mut inner) => inner.poll_ready(), - EitherService::B(ref mut inner) => inner.poll_ready(), + let left = self.left.poll_ready()?; + let right = self.right.poll_ready()?; + + if left.is_ready() && right.is_ready() { + Ok(Async::Ready(())) + } else { + Ok(Async::NotReady) } } - fn call(&mut self, req: A::Request) -> Self::Future { - match self { - EitherService::A(ref mut inner) => future::Either::A(inner.call(req)), - EitherService::B(ref mut inner) => future::Either::B(inner.call(req)), + fn call(&mut self, req: either::Either) -> Self::Future { + match req { + either::Either::Left(req) => future::Either::A(self.left.call(req)), + either::Either::Right(req) => future::Either::B(self.right.call(req)), } } } -/// Combine two different new service types into a single type. -pub enum Either { - A(A), - B(B), +/// Combine two different new service types into a single service. +pub struct Either { + left: A, + right: B, } impl Either { - pub fn new_a(srv: A) -> Self + pub fn new_a(srv: F) -> Either where - A: NewService, - B: NewService< - C, - Request = A::Request, - Response = A::Response, - Error = A::Error, - InitError = A::InitError, - >, + A: NewService, + F: IntoNewService, { - Either::A(srv) + Either { + left: srv.into_new_service(), + right: (), + } } - pub fn new_b(srv: B) -> Self + pub fn new_b(srv: F) -> Either<(), B> where - A: NewService, - B: NewService< - C, - Request = A::Request, - Response = A::Response, - Error = A::Error, - InitError = A::InitError, - >, + B: NewService, + F: IntoNewService, { - Either::B(srv) + Either { + left: (), + right: srv.into_new_service(), + } } } -impl NewService for Either +impl NewService for Either where - A: NewService, + A: NewService, B: NewService< - C, - Request = A::Request, + Config = A::Config, Response = A::Response, Error = A::Error, InitError = A::InitError, >, { - type Request = A::Request; + type Request = either::Either; type Response = A::Response; type Error = A::Error; type InitError = A::InitError; + type Config = A::Config; type Service = EitherService; - type Future = EitherNewService; + type Future = EitherNewService; - fn new_service(&self, cfg: &C) -> Self::Future { - match self { - Either::A(ref inner) => EitherNewService::A(inner.new_service(cfg)), - Either::B(ref inner) => EitherNewService::B(inner.new_service(cfg)), + fn new_service(&self, cfg: &A::Config) -> Self::Future { + EitherNewService { + left: None, + right: None, + left_fut: self.left.new_service(cfg), + right_fut: self.right.new_service(cfg), } } } impl Clone for Either { fn clone(&self) -> Self { - match self { - Either::A(srv) => Either::A(srv.clone()), - Either::B(srv) => Either::B(srv.clone()), + Self { + left: self.left.clone(), + right: self.right.clone(), } } } #[doc(hidden)] -pub enum EitherNewService, B: NewService, C> { - A(::Future), - B(::Future), +pub struct EitherNewService { + left: Option, + right: Option, + left_fut: ::Future, + right_fut: ::Future, } -impl Future for EitherNewService +impl Future for EitherNewService where - A: NewService, - B: NewService< - C, - Request = A::Request, - Response = A::Response, - Error = A::Error, - InitError = A::InitError, - >, + A: NewService, + B: NewService, { type Item = EitherService; type Error = A::InitError; fn poll(&mut self) -> Poll { - match self { - EitherNewService::A(ref mut fut) => { - let service = try_ready!(fut.poll()); - Ok(Async::Ready(EitherService::A(service))) - } - EitherNewService::B(ref mut fut) => { - let service = try_ready!(fut.poll()); - Ok(Async::Ready(EitherService::B(service))) - } + if self.left.is_none() { + self.left = Some(try_ready!(self.left_fut.poll())); + } + if self.right.is_none() { + self.right = Some(try_ready!(self.right_fut.poll())); + } + + if self.left.is_some() && self.right.is_some() { + Ok(Async::Ready(EitherService { + left: self.left.take().unwrap(), + right: self.right.take().unwrap(), + })) + } else { + Ok(Async::NotReady) } } } diff --git a/actix-utils/src/framed.rs b/actix-utils/src/framed.rs index 44fe9d85..4633d51c 100644 --- a/actix-utils/src/framed.rs +++ b/actix-utils/src/framed.rs @@ -1,14 +1,12 @@ //! Framed dispatcher service and related utilities use std::collections::VecDeque; -use std::marker::PhantomData; -use std::mem; +use std::{fmt, mem}; use actix_codec::{AsyncRead, AsyncWrite, Decoder, Encoder, Framed}; -use actix_service::{IntoNewService, IntoService, NewService, Service}; -use futures::future::{ok, FutureResult}; +use actix_service::{IntoService, Service}; use futures::task::AtomicTask; use futures::unsync::mpsc; -use futures::{Async, Future, IntoFuture, Poll, Sink, Stream}; +use futures::{Async, Future, Poll, Sink, Stream}; use log::debug; use crate::cell::Cell; @@ -16,156 +14,6 @@ use crate::cell::Cell; type Request = ::Item; type Response = ::Item; -pub struct FramedNewService { - factory: S, - _t: PhantomData<(T, U, C)>, -} - -impl FramedNewService -where - C: Clone, - S: NewService, Response = Response>, - S::Error: 'static, - ::Future: 'static, - T: AsyncRead + AsyncWrite, - U: Decoder + Encoder, - ::Item: 'static, - ::Error: std::fmt::Debug, -{ - pub fn new>(factory: F1) -> Self { - Self { - factory: factory.into_new_service(), - _t: PhantomData, - } - } -} - -impl Clone for FramedNewService -where - S: Clone, -{ - fn clone(&self) -> Self { - Self { - factory: self.factory.clone(), - _t: PhantomData, - } - } -} - -impl NewService for FramedNewService -where - C: Clone, - S: NewService, Response = Response> + Clone, - S::Error: 'static, - ::Future: 'static, - T: AsyncRead + AsyncWrite, - U: Decoder + Encoder, - ::Item: 'static, - ::Error: std::fmt::Debug, -{ - type Request = Framed; - type Response = FramedTransport; - type Error = S::InitError; - type InitError = S::InitError; - type Service = FramedService; - type Future = FutureResult; - - fn new_service(&self, cfg: &C) -> Self::Future { - ok(FramedService { - factory: self.factory.clone(), - config: cfg.clone(), - _t: PhantomData, - }) - } -} - -pub struct FramedService { - factory: S, - config: C, - _t: PhantomData<(T, U)>, -} - -impl Clone for FramedService -where - S: Clone, - C: Clone, -{ - fn clone(&self) -> Self { - Self { - factory: self.factory.clone(), - config: self.config.clone(), - _t: PhantomData, - } - } -} - -impl Service for FramedService -where - S: NewService, Response = Response>, - S::Error: 'static, - ::Future: 'static, - T: AsyncRead + AsyncWrite, - U: Decoder + Encoder, - ::Item: 'static, - ::Error: std::fmt::Debug, - C: Clone, -{ - type Request = Framed; - type Response = FramedTransport; - type Error = S::InitError; - type Future = FramedServiceResponseFuture; - - fn poll_ready(&mut self) -> Poll<(), Self::Error> { - Ok(Async::Ready(())) - } - - fn call(&mut self, req: Framed) -> Self::Future { - FramedServiceResponseFuture { - fut: self.factory.new_service(&self.config), - framed: Some(req), - } - } -} - -#[doc(hidden)] -pub struct FramedServiceResponseFuture -where - S: NewService, Response = Response>, - S::Error: 'static, - ::Future: 'static, - T: AsyncRead + AsyncWrite, - U: Decoder + Encoder, - ::Item: 'static, - ::Error: std::fmt::Debug, -{ - fut: ::Future, - framed: Option>, -} - -impl Future for FramedServiceResponseFuture -where - S: NewService, Response = Response>, - S::Error: 'static, - ::Future: 'static, - T: AsyncRead + AsyncWrite, - U: Decoder + Encoder, - ::Item: 'static, - ::Error: std::fmt::Debug, -{ - type Item = FramedTransport; - type Error = S::InitError; - - fn poll(&mut self) -> Poll { - match self.fut.poll()? { - Async::NotReady => Ok(Async::NotReady), - Async::Ready(service) => Ok(Async::Ready(FramedTransport::new( - self.framed.take().unwrap(), - service, - ))), - } - } -} - /// Framed transport errors pub enum FramedTransportError { Service(E), @@ -179,6 +27,42 @@ impl From for FramedTransportError { } } +impl fmt::Debug for FramedTransportError +where + E: fmt::Debug, + ::Error: fmt::Debug, + ::Error: fmt::Debug, +{ + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + match *self { + FramedTransportError::Service(ref e) => { + write!(fmt, "FramedTransportError::Service({:?})", e) + } + FramedTransportError::Encoder(ref e) => { + write!(fmt, "FramedTransportError::Encoder({:?})", e) + } + FramedTransportError::Decoder(ref e) => { + write!(fmt, "FramedTransportError::Encoder({:?})", e) + } + } + } +} + +impl fmt::Display for FramedTransportError +where + E: fmt::Display, + ::Error: fmt::Debug, + ::Error: fmt::Debug, +{ + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + match *self { + FramedTransportError::Service(ref e) => write!(fmt, "{}", e), + FramedTransportError::Encoder(ref e) => write!(fmt, "{:?}", e), + FramedTransportError::Decoder(ref e) => write!(fmt, "{:?}", e), + } + } +} + pub enum FramedMessage { Message(T), Close, @@ -444,78 +328,3 @@ where } } } - -pub struct IntoFramed -where - T: AsyncRead + AsyncWrite, - F: Fn() -> U + Send + Clone + 'static, - U: Encoder + Decoder, -{ - factory: F, - _t: PhantomData<(T,)>, -} - -impl IntoFramed -where - T: AsyncRead + AsyncWrite, - F: Fn() -> U + Send + Clone + 'static, - U: Encoder + Decoder, -{ - pub fn new(factory: F) -> Self { - IntoFramed { - factory, - _t: PhantomData, - } - } -} - -impl NewService for IntoFramed -where - T: AsyncRead + AsyncWrite, - F: Fn() -> U + Send + Clone + 'static, - U: Encoder + Decoder, -{ - type Request = T; - type Response = Framed; - type Error = (); - type InitError = (); - type Service = IntoFramedService; - type Future = FutureResult; - - fn new_service(&self, _: &C) -> Self::Future { - ok(IntoFramedService { - factory: self.factory.clone(), - _t: PhantomData, - }) - } -} - -pub struct IntoFramedService -where - T: AsyncRead + AsyncWrite, - F: Fn() -> U + Send + Clone + 'static, - U: Encoder + Decoder, -{ - factory: F, - _t: PhantomData<(T,)>, -} - -impl Service for IntoFramedService -where - T: AsyncRead + AsyncWrite, - F: Fn() -> U + Send + Clone + 'static, - U: Encoder + Decoder, -{ - type Request = T; - type Response = Framed; - type Error = (); - type Future = FutureResult; - - fn poll_ready(&mut self) -> Poll<(), Self::Error> { - Ok(Async::Ready(())) - } - - fn call(&mut self, req: T) -> Self::Future { - ok(Framed::new(req, (self.factory)())) - } -} diff --git a/actix-utils/src/inflight.rs b/actix-utils/src/inflight.rs index 46030e86..d1c3b093 100644 --- a/actix-utils/src/inflight.rs +++ b/actix-utils/src/inflight.rs @@ -1,4 +1,6 @@ -use actix_service::{IntoService, Service, Transform, Void}; +use std::convert::Infallible; + +use actix_service::{IntoService, Service, Transform}; use futures::future::{ok, FutureResult}; use futures::{Async, Future, Poll}; @@ -28,7 +30,7 @@ impl Transform for InFlight { type Request = S::Request; type Response = S::Response; type Error = S::Error; - type InitError = Void; + type InitError = Infallible; type Transform = InFlightService; type Future = FutureResult; diff --git a/actix-utils/src/keepalive.rs b/actix-utils/src/keepalive.rs index 81305423..05436d7d 100644 --- a/actix-utils/src/keepalive.rs +++ b/actix-utils/src/keepalive.rs @@ -1,7 +1,8 @@ +use std::convert::Infallible; use std::marker::PhantomData; use std::time::{Duration, Instant}; -use actix_service::{NewService, Service, Void}; +use actix_service::{NewService, Service}; use futures::future::{ok, FutureResult}; use futures::{Async, Future, Poll}; use tokio_timer::Delay; @@ -43,14 +44,15 @@ where } } -impl NewService<()> for KeepAlive +impl NewService for KeepAlive where F: Fn() -> E + Clone, { type Request = R; type Response = R; type Error = E; - type InitError = Void; + type InitError = Infallible; + type Config = (); type Service = KeepAliveService; type Future = FutureResult; diff --git a/actix-utils/src/order.rs b/actix-utils/src/order.rs index f4cebfa0..cffb123f 100644 --- a/actix-utils/src/order.rs +++ b/actix-utils/src/order.rs @@ -1,9 +1,10 @@ use std::collections::VecDeque; +use std::convert::Infallible; use std::fmt; use std::marker::PhantomData; use std::rc::Rc; -use actix_service::{IntoService, Service, Transform, Void}; +use actix_service::{IntoService, Service, Transform}; use futures::future::{ok, FutureResult}; use futures::task::AtomicTask; use futures::unsync::oneshot; @@ -90,7 +91,7 @@ where type Request = S::Request; type Response = S::Response; type Error = InOrderError; - type InitError = Void; + type InitError = Infallible; type Transform = InOrderService; type Future = FutureResult; diff --git a/actix-utils/src/stream.rs b/actix-utils/src/stream.rs index 7274fa56..68377355 100644 --- a/actix-utils/src/stream.rs +++ b/actix-utils/src/stream.rs @@ -1,10 +1,9 @@ use std::marker::PhantomData; use std::rc::Rc; -use actix_service::{IntoNewService, IntoService, NewService, Service}; -use futures::future::{ok, Future, FutureResult}; +use actix_service::{IntoService, NewService, Service}; use futures::unsync::mpsc; -use futures::{Async, Poll, Stream}; +use futures::{Async, Future, Poll, Stream}; type Request = Result<::Item, ::Error>; @@ -29,76 +28,19 @@ where } } -pub struct StreamNewService { +pub struct StreamService { factory: Rc, - _t: PhantomData<(S, E, C)>, -} - -impl StreamNewService -where - C: Clone, - S: IntoStream, - T: NewService, Response = (), Error = E, InitError = E>, - T::Future: 'static, - T::Service: 'static, - ::Future: 'static, -{ - pub fn new>(factory: F) -> Self { - Self { - factory: Rc::new(factory.into_new_service()), - _t: PhantomData, - } - } -} - -impl Clone for StreamNewService { - fn clone(&self) -> Self { - Self { - factory: self.factory.clone(), - _t: PhantomData, - } - } -} - -impl NewService for StreamNewService -where - C: Clone, - S: IntoStream + 'static, - T: NewService, Response = (), Error = E, InitError = E>, - T::Future: 'static, - T::Service: 'static, - ::Future: 'static, -{ - type Request = S; - type Response = (); - type Error = E; - type InitError = E; - type Service = StreamService; - type Future = FutureResult; - - fn new_service(&self, cfg: &C) -> Self::Future { - ok(StreamService { - factory: self.factory.clone(), - config: cfg.clone(), - _t: PhantomData, - }) - } -} - -pub struct StreamService { - factory: Rc, - config: C, + config: T::Config, _t: PhantomData<(S, E)>, } -impl Service for StreamService +impl Service for StreamService where S: IntoStream + 'static, - T: NewService, Response = (), Error = E, InitError = E>, + T: NewService, Response = (), Error = E, InitError = E>, T::Future: 'static, T::Service: 'static, ::Future: 'static, - C: Clone, { type Request = S; type Response = (); @@ -207,83 +149,3 @@ impl Future for StreamDispatcherService { } } } - -/// `NewService` that implements, read one item from the stream. -pub struct TakeItem { - _t: PhantomData, -} - -impl TakeItem { - /// Create new `TakeRequest` instance. - pub fn new() -> Self { - TakeItem { _t: PhantomData } - } -} - -impl Default for TakeItem { - fn default() -> Self { - TakeItem { _t: PhantomData } - } -} - -impl Clone for TakeItem { - fn clone(&self) -> TakeItem { - TakeItem { _t: PhantomData } - } -} - -impl NewService for TakeItem { - type Request = T; - type Response = (Option, T); - type Error = T::Error; - type InitError = (); - type Service = TakeItemService; - type Future = FutureResult; - - fn new_service(&self, _: &C) -> Self::Future { - ok(TakeItemService { _t: PhantomData }) - } -} - -/// `NewService` that implements, read one request from framed object feature. -pub struct TakeItemService { - _t: PhantomData, -} - -impl Clone for TakeItemService { - fn clone(&self) -> TakeItemService { - TakeItemService { _t: PhantomData } - } -} - -impl Service for TakeItemService { - type Request = T; - type Response = (Option, T); - type Error = T::Error; - type Future = TakeItemServiceResponse; - - fn poll_ready(&mut self) -> Poll<(), Self::Error> { - Ok(Async::Ready(())) - } - - fn call(&mut self, req: T) -> Self::Future { - TakeItemServiceResponse { stream: Some(req) } - } -} - -#[doc(hidden)] -pub struct TakeItemServiceResponse { - stream: Option, -} - -impl Future for TakeItemServiceResponse { - type Item = (Option, T); - type Error = T::Error; - - fn poll(&mut self) -> Poll { - match self.stream.as_mut().expect("Use after finish").poll()? { - Async::Ready(item) => Ok(Async::Ready((item, self.stream.take().unwrap()))), - Async::NotReady => Ok(Async::NotReady), - } - } -} diff --git a/actix-utils/src/time.rs b/actix-utils/src/time.rs index c30052d0..0138ec3e 100644 --- a/actix-utils/src/time.rs +++ b/actix-utils/src/time.rs @@ -1,6 +1,7 @@ +use std::convert::Infallible; use std::time::{self, Duration, Instant}; -use actix_service::{NewService, Service, Void}; +use actix_service::{NewService, Service}; use futures::future::{ok, FutureResult}; use futures::{Async, Future, Poll}; use tokio_timer::sleep; @@ -41,11 +42,12 @@ impl Default for LowResTime { } } -impl NewService<()> for LowResTime { +impl NewService for LowResTime { type Request = (); type Response = Instant; - type Error = Void; - type InitError = Void; + type Error = Infallible; + type InitError = Infallible; + type Config = (); type Service = LowResTimeService; type Future = FutureResult; @@ -91,7 +93,7 @@ impl LowResTimeService { impl Service for LowResTimeService { type Request = (); type Response = Instant; - type Error = Void; + type Error = Infallible; type Future = FutureResult; fn poll_ready(&mut self) -> Poll<(), Self::Error> { diff --git a/examples/basic.rs b/examples/basic.rs index 44d3c0c3..5ff109d2 100644 --- a/examples/basic.rs +++ b/examples/basic.rs @@ -10,7 +10,7 @@ use std::{env, fmt, io}; use actix_codec::{AsyncRead, AsyncWrite}; use actix_rt::System; use actix_server::{Io, Server}; -use actix_service::{fn_service, NewService}; +use actix_service::{service_fn, NewService}; use futures::{future, Future}; use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod}; use tokio_openssl::SslAcceptorExt; @@ -54,14 +54,14 @@ fn main() -> io::Result<()> { let acceptor = acceptor.clone(); // service for converting incoming TcpStream to a SslStream - fn_service(move |stream: Io| { + service_fn(move |stream: Io| { SslAcceptorExt::accept_async(&acceptor, stream.into_parts().0) .map_err(|e| println!("Openssl error: {}", e)) }) // .and_then() combinator uses other service to convert incoming `Request` to a // `Response` and then uses that response as an input for next // service. in this case, on success we use `logger` service - .and_then(fn_service(logger)) + .and_then(logger) // Next service counts number of connections .and_then(move |_| { let num = num.fetch_add(1, Ordering::Relaxed);