1
0
mirror of https://github.com/fafhrd91/actix-net synced 2024-12-03 19:42:13 +01:00

Use associated type for NewService config

This commit is contained in:
Nikolay Kim 2019-05-12 06:03:50 -07:00
parent 76c317e0b2
commit f0776fca94
46 changed files with 810 additions and 1010 deletions

View File

@ -37,3 +37,9 @@ futures = "0.1.25"
openssl = "0.10" openssl = "0.10"
tokio-tcp = "0.1" tokio-tcp = "0.1"
tokio-openssl = "0.3" 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" }

View File

@ -1,5 +1,12 @@
# Changes # Changes
## [0.2.0] - 2019-05-11
### Changed
* Upgrade to actix-service 0.4
## [0.1.5] - 2019-04-19 ## [0.1.5] - 2019-04-19
### Added ### Added

View File

@ -30,6 +30,7 @@ impl<T: Address> NewService for TcpConnectorFactory<T> {
type Request = Connect<T>; type Request = Connect<T>;
type Response = Connection<T, TcpStream>; type Response = Connection<T, TcpStream>;
type Error = ConnectError; type Error = ConnectError;
type Config = ();
type Service = TcpConnector<T>; type Service = TcpConnector<T>;
type InitError = (); type InitError = ();
type Future = FutureResult<Self::Service, Self::InitError>; type Future = FutureResult<Self::Service, Self::InitError>;

View File

@ -31,17 +31,6 @@ pub use self::resolver::{Resolver, ResolverFactory};
use actix_service::{NewService, Service, ServiceExt}; use actix_service::{NewService, Service, ServiceExt};
use tokio_tcp::TcpStream; use tokio_tcp::TcpStream;
#[doc(hidden)]
#[deprecated(since = "0.1.2", note = "please use `actix_connect::TcpConnector`")]
pub type Connector<T> = TcpConnector<T>;
#[doc(hidden)]
#[deprecated(
since = "0.1.2",
note = "please use `actix_connect::TcpConnectorFactory`"
)]
pub type ConnectorFactory<T> = TcpConnectorFactory<T>;
pub fn start_resolver(cfg: ResolverConfig, opts: ResolverOpts) -> AsyncResolver { pub fn start_resolver(cfg: ResolverConfig, opts: ResolverOpts) -> AsyncResolver {
let (resolver, bg) = AsyncResolver::new(cfg, opts); let (resolver, bg) = AsyncResolver::new(cfg, opts);
tokio_current_thread::spawn(bg); tokio_current_thread::spawn(bg);
@ -90,6 +79,7 @@ pub fn new_connector<T: Address>(
pub fn new_connector_factory<T: Address>( pub fn new_connector_factory<T: Address>(
resolver: AsyncResolver, resolver: AsyncResolver,
) -> impl NewService< ) -> impl NewService<
Config = (),
Request = Connect<T>, Request = Connect<T>,
Response = Connection<T, TcpStream>, Response = Connection<T, TcpStream>,
Error = ConnectError, Error = ConnectError,
@ -107,6 +97,7 @@ pub fn default_connector<T: Address>(
/// Create connector service factory with default parameters /// Create connector service factory with default parameters
pub fn default_connector_factory<T: Address>() -> impl NewService< pub fn default_connector_factory<T: Address>() -> impl NewService<
Config = (),
Request = Connect<T>, Request = Connect<T>,
Response = Connection<T, TcpStream>, Response = Connection<T, TcpStream>,
Error = ConnectError, Error = ConnectError,

View File

@ -50,6 +50,7 @@ impl<T: Address> NewService for ResolverFactory<T> {
type Request = Connect<T>; type Request = Connect<T>;
type Response = Connect<T>; type Response = Connect<T>;
type Error = ConnectError; type Error = ConnectError;
type Config = ();
type Service = Resolver<T>; type Service = Resolver<T>;
type InitError = (); type InitError = ();
type Future = FutureResult<Self::Service, Self::InitError>; type Future = FutureResult<Self::Service, Self::InitError>;

View File

@ -52,13 +52,14 @@ impl<T, U> Clone for OpensslConnector<T, U> {
} }
} }
impl<T: Address, U> NewService<()> for OpensslConnector<T, U> impl<T: Address, U> NewService for OpensslConnector<T, U>
where where
U: AsyncRead + AsyncWrite + fmt::Debug, U: AsyncRead + AsyncWrite + fmt::Debug,
{ {
type Request = Connection<T, U>; type Request = Connection<T, U>;
type Response = Connection<T, SslStream<U>>; type Response = Connection<T, SslStream<U>>;
type Error = HandshakeError<U>; type Error = HandshakeError<U>;
type Config = ();
type Service = OpensslConnectorService<T, U>; type Service = OpensslConnectorService<T, U>;
type InitError = (); type InitError = ();
type Future = FutureResult<Self::Service, Self::InitError>; type Future = FutureResult<Self::Service, Self::InitError>;

View File

@ -1,6 +1,6 @@
use actix_codec::{BytesCodec, Framed}; use actix_codec::{BytesCodec, Framed};
use actix_server_config::Io; 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 actix_test_server::TestServer;
use bytes::Bytes; use bytes::Bytes;
use futures::{future::lazy, Future, Sink}; use futures::{future::lazy, Future, Sink};
@ -13,7 +13,7 @@ use actix_connect::{default_connector, Connect};
#[test] #[test]
fn test_string() { fn test_string() {
let mut srv = TestServer::with(|| { let mut srv = TestServer::with(|| {
fn_service(|io: Io<tokio_tcp::TcpStream>| { service_fn(|io: Io<tokio_tcp::TcpStream>| {
Framed::new(io.into_parts().0, BytesCodec) Framed::new(io.into_parts().0, BytesCodec)
.send(Bytes::from_static(b"test")) .send(Bytes::from_static(b"test"))
.then(|_| Ok::<_, ()>(())) .then(|_| Ok::<_, ()>(()))
@ -29,7 +29,7 @@ fn test_string() {
#[test] #[test]
fn test_static_str() { fn test_static_str() {
let mut srv = TestServer::with(|| { let mut srv = TestServer::with(|| {
fn_service(|io: Io<tokio_tcp::TcpStream>| { service_fn(|io: Io<tokio_tcp::TcpStream>| {
Framed::new(io.into_parts().0, BytesCodec) Framed::new(io.into_parts().0, BytesCodec)
.send(Bytes::from_static(b"test")) .send(Bytes::from_static(b"test"))
.then(|_| Ok::<_, ()>(())) .then(|_| Ok::<_, ()>(()))
@ -63,7 +63,7 @@ fn test_static_str() {
#[test] #[test]
fn test_new_service() { fn test_new_service() {
let mut srv = TestServer::with(|| { let mut srv = TestServer::with(|| {
fn_service(|io: Io<tokio_tcp::TcpStream>| { service_fn(|io: Io<tokio_tcp::TcpStream>| {
Framed::new(io.into_parts().0, BytesCodec) Framed::new(io.into_parts().0, BytesCodec)
.send(Bytes::from_static(b"test")) .send(Bytes::from_static(b"test"))
.then(|_| Ok::<_, ()>(())) .then(|_| Ok::<_, ()>(()))
@ -95,7 +95,7 @@ fn test_new_service() {
#[test] #[test]
fn test_uri() { fn test_uri() {
let mut srv = TestServer::with(|| { let mut srv = TestServer::with(|| {
fn_service(|io: Io<tokio_tcp::TcpStream>| { service_fn(|io: Io<tokio_tcp::TcpStream>| {
Framed::new(io.into_parts().0, BytesCodec) Framed::new(io.into_parts().0, BytesCodec)
.send(Bytes::from_static(b"test")) .send(Bytes::from_static(b"test"))
.then(|_| Ok::<_, ()>(())) .then(|_| Ok::<_, ()>(()))

View File

@ -1,5 +1,16 @@
# Changes # 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 ## [0.4.3] - 2019-04-16
### Added ### Added

View File

@ -207,8 +207,8 @@ impl ServiceRuntime {
/// *ServiceConfig::bind()* or *ServiceConfig::listen()* methods. /// *ServiceConfig::bind()* or *ServiceConfig::listen()* methods.
pub fn service<T, F>(&mut self, name: &str, service: F) pub fn service<T, F>(&mut self, name: &str, service: F)
where where
F: IntoNewService<T, ServerConfig>, F: IntoNewService<T>,
T: NewService<ServerConfig, Request = Io<TcpStream>> + 'static, T: NewService<Config = ServerConfig, Request = Io<TcpStream>> + 'static,
T::Future: 'static, T::Future: 'static,
T::Service: 'static, T::Service: 'static,
T::InitError: fmt::Debug, T::InitError: fmt::Debug,
@ -237,11 +237,11 @@ impl ServiceRuntime {
type BoxedNewService = Box< type BoxedNewService = Box<
NewService< NewService<
ServerConfig,
Request = (Option<CounterGuard>, ServerMessage), Request = (Option<CounterGuard>, ServerMessage),
Response = (), Response = (),
Error = (), Error = (),
InitError = (), InitError = (),
Config = ServerConfig,
Service = BoxedServerService, Service = BoxedServerService,
Future = Box<Future<Item = BoxedServerService, Error = ()>>, Future = Box<Future<Item = BoxedServerService, Error = ()>>,
>, >,
@ -251,9 +251,9 @@ struct ServiceFactory<T> {
inner: T, inner: T,
} }
impl<T> NewService<ServerConfig> for ServiceFactory<T> impl<T> NewService for ServiceFactory<T>
where where
T: NewService<ServerConfig, Request = Io<TcpStream>>, T: NewService<Config = ServerConfig, Request = Io<TcpStream>>,
T::Future: 'static, T::Future: 'static,
T::Service: 'static, T::Service: 'static,
T::Error: 'static, T::Error: 'static,
@ -263,6 +263,7 @@ where
type Response = (); type Response = ();
type Error = (); type Error = ();
type InitError = (); type InitError = ();
type Config = ServerConfig;
type Service = BoxedServerService; type Service = BoxedServerService;
type Future = Box<Future<Item = BoxedServerService, Error = ()>>; type Future = Box<Future<Item = BoxedServerService, Error = ()>>;

View File

@ -24,7 +24,7 @@ pub(crate) enum ServerMessage {
} }
pub trait ServiceFactory: Send + Clone + 'static { pub trait ServiceFactory: Send + Clone + 'static {
type NewService: NewService<ServerConfig, Request = Io<TcpStream>>; type NewService: NewService<Config = ServerConfig, Request = Io<TcpStream>>;
fn create(&self) -> Self::NewService; fn create(&self) -> Self::NewService;
} }
@ -169,7 +169,7 @@ impl InternalServiceFactory for Box<InternalServiceFactory> {
impl<F, T> ServiceFactory for F impl<F, T> ServiceFactory for F
where where
F: Fn() -> T + Send + Clone + 'static, F: Fn() -> T + Send + Clone + 'static,
T: NewService<ServerConfig, Request = Io<TcpStream>>, T: NewService<Config = ServerConfig, Request = Io<TcpStream>>,
{ {
type NewService = T; type NewService = T;

View File

@ -35,6 +35,7 @@ thread_local! {
} }
/// Ssl error combinded with service error. /// Ssl error combinded with service error.
#[derive(Debug)]
pub enum SslError<E1, E2> { pub enum SslError<E1, E2> {
Ssl(E1), Ssl(E1),
Service(E2), Service(E2),

View File

@ -37,10 +37,12 @@ impl<T: AsyncRead + AsyncWrite, P> Clone for NativeTlsAcceptor<T, P> {
} }
} }
impl<T: AsyncRead + AsyncWrite, P> NewService<ServerConfig> for NativeTlsAcceptor<T, P> { impl<T: AsyncRead + AsyncWrite, P> NewService for NativeTlsAcceptor<T, P> {
type Request = Io<T, P>; type Request = Io<T, P>;
type Response = Io<TlsStream<T>, P>; type Response = Io<TlsStream<T>, P>;
type Error = Error; type Error = Error;
type Config = ServerConfig;
type Service = NativeTlsAcceptorService<T, P>; type Service = NativeTlsAcceptorService<T, P>;
type InitError = (); type InitError = ();
type Future = FutureResult<Self::Service, Self::InitError>; type Future = FutureResult<Self::Service, Self::InitError>;

View File

@ -37,10 +37,11 @@ impl<T: AsyncRead + AsyncWrite, P> Clone for OpensslAcceptor<T, P> {
} }
} }
impl<T: AsyncRead + AsyncWrite, P> NewService<ServerConfig> for OpensslAcceptor<T, P> { impl<T: AsyncRead + AsyncWrite, P> NewService for OpensslAcceptor<T, P> {
type Request = Io<T, P>; type Request = Io<T, P>;
type Response = Io<SslStream<T>, P>; type Response = Io<SslStream<T>, P>;
type Error = HandshakeError<T>; type Error = HandshakeError<T>;
type Config = ServerConfig;
type Service = OpensslAcceptorService<T, P>; type Service = OpensslAcceptorService<T, P>;
type InitError = (); type InitError = ();
type Future = FutureResult<Self::Service, Self::InitError>; type Future = FutureResult<Self::Service, Self::InitError>;

View File

@ -39,10 +39,12 @@ impl<T, P> Clone for RustlsAcceptor<T, P> {
} }
} }
impl<T: AsyncRead + AsyncWrite, P> NewService<SrvConfig> for RustlsAcceptor<T, P> { impl<T: AsyncRead + AsyncWrite, P> NewService for RustlsAcceptor<T, P> {
type Request = Io<T, P>; type Request = Io<T, P>;
type Response = Io<TlsStream<T, ServerSession>, P>; type Response = Io<TlsStream<T, ServerSession>, P>;
type Error = io::Error; type Error = io::Error;
type Config = SrvConfig;
type Service = RustlsAcceptorService<T, P>; type Service = RustlsAcceptorService<T, P>;
type InitError = (); type InitError = ();
type Future = FutureResult<Self::Service, Self::InitError>; type Future = FutureResult<Self::Service, Self::InitError>;

View File

@ -4,7 +4,7 @@ use std::{net, thread, time};
use actix_codec::{BytesCodec, Framed}; use actix_codec::{BytesCodec, Framed};
use actix_server::{Io, Server, ServerConfig}; 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 bytes::Bytes;
use futures::{Future, Sink}; use futures::{Future, Sink};
use net2::TcpBuilder; use net2::TcpBuilder;
@ -28,7 +28,7 @@ fn test_bind() {
let sys = actix_rt::System::new("test"); let sys = actix_rt::System::new("test");
let srv = Server::build() let srv = Server::build()
.bind("test", addr, move || { .bind("test", addr, move || {
fn_cfg_factory(move |cfg: &ServerConfig| { new_service_cfg(move |cfg: &ServerConfig| {
assert_eq!(cfg.local_addr(), addr); assert_eq!(cfg.local_addr(), addr);
Ok::<_, ()>((|_| Ok::<_, ()>(())).into_service()) Ok::<_, ()>((|_| Ok::<_, ()>(())).into_service())
}) })
@ -54,7 +54,7 @@ fn test_bind_no_config() {
let h = thread::spawn(move || { let h = thread::spawn(move || {
let sys = actix_rt::System::new("test"); let sys = actix_rt::System::new("test");
let srv = Server::build() let srv = Server::build()
.bind("test", addr, move || fn_service(|_| Ok::<_, ()>(()))) .bind("test", addr, move || service_fn(|_| Ok::<_, ()>(())))
.unwrap() .unwrap()
.start(); .start();
let _ = tx.send((srv, actix_rt::System::current())); let _ = tx.send((srv, actix_rt::System::current()));
@ -76,7 +76,7 @@ fn test_listen() {
let lst = net::TcpListener::bind(addr).unwrap(); let lst = net::TcpListener::bind(addr).unwrap();
let srv = Server::build() let srv = Server::build()
.listen("test", lst, move || { .listen("test", lst, move || {
fn_cfg_factory(move |cfg: &ServerConfig| { new_service_cfg(move |cfg: &ServerConfig| {
assert_eq!(cfg.local_addr(), addr); assert_eq!(cfg.local_addr(), addr);
Ok::<_, ()>((|_| Ok::<_, ()>(())).into_service()) Ok::<_, ()>((|_| Ok::<_, ()>(())).into_service())
}) })
@ -105,7 +105,7 @@ fn test_start() {
let srv = Server::build() let srv = Server::build()
.backlog(100) .backlog(100)
.bind("test", addr, move || { .bind("test", addr, move || {
fn_cfg_factory(move |cfg: &ServerConfig| { new_service_cfg(move |cfg: &ServerConfig| {
assert_eq!(cfg.local_addr(), addr); assert_eq!(cfg.local_addr(), addr);
Ok::<_, ()>( Ok::<_, ()>(
(|io: Io<TcpStream>| { (|io: Io<TcpStream>| {

View File

@ -1,5 +1,20 @@
# Changes # 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 ## [0.3.6] - 2019-04-07
### Changed ### Changed

View File

@ -23,8 +23,7 @@ name = "actix_service"
path = "src/lib.rs" path = "src/lib.rs"
[dependencies] [dependencies]
futures = "0.1.24" futures = "0.1.25"
void = "1.0.2"
[dev-dependencies] [dev-dependencies]
actix-rt = "0.2" actix-rt = "0.2"

View File

@ -1,5 +1,3 @@
use std::marker::PhantomData;
use futures::{Async, Future, Poll}; use futures::{Async, Future, Poll};
use super::{IntoNewService, NewService, Service}; use super::{IntoNewService, NewService, Service};
@ -111,67 +109,75 @@ where
} }
/// `AndThenNewService` new service combinator /// `AndThenNewService` new service combinator
pub struct AndThenNewService<A, B, C> pub struct AndThenNewService<A, B>
where where
A: NewService<C>, A: NewService,
B: NewService<C, Request = A::Response, Error = A::Error, InitError = A::InitError>, B: NewService,
{ {
a: A, a: A,
b: B, b: B,
_t: PhantomData<C>,
} }
impl<A, B, C> AndThenNewService<A, B, C> impl<A, B> AndThenNewService<A, B>
where where
A: NewService<C>, A: NewService,
B: NewService<C, Request = A::Response, Error = A::Error, InitError = A::InitError>, B: NewService<
Config = A::Config,
Request = A::Response,
Error = A::Error,
InitError = A::InitError,
>,
{ {
/// Create new `AndThen` combinator /// Create new `AndThen` combinator
pub fn new<F: IntoNewService<B, C>>(a: A, f: F) -> Self { pub fn new<F: IntoNewService<B>>(a: A, f: F) -> Self {
Self { Self {
a, a,
b: f.into_new_service(), b: f.into_new_service(),
_t: PhantomData,
} }
} }
} }
impl<A, B, C> NewService<C> for AndThenNewService<A, B, C> impl<A, B> NewService for AndThenNewService<A, B>
where where
A: NewService<C>, A: NewService,
B: NewService<C, Request = A::Response, Error = A::Error, InitError = A::InitError>, B: NewService<
Config = A::Config,
Request = A::Response,
Error = A::Error,
InitError = A::InitError,
>,
{ {
type Request = A::Request; type Request = A::Request;
type Response = B::Response; type Response = B::Response;
type Error = A::Error; type Error = A::Error;
type Config = A::Config;
type Service = AndThen<A::Service, B::Service>; type Service = AndThen<A::Service, B::Service>;
type InitError = A::InitError; type InitError = A::InitError;
type Future = AndThenNewServiceFuture<A, B, C>; type Future = AndThenNewServiceFuture<A, B>;
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)) AndThenNewServiceFuture::new(self.a.new_service(cfg), self.b.new_service(cfg))
} }
} }
impl<A, B, C> Clone for AndThenNewService<A, B, C> impl<A, B> Clone for AndThenNewService<A, B>
where where
A: NewService<C> + Clone, A: NewService + Clone,
B: NewService<C, Request = A::Response, Error = A::Error, InitError = A::InitError> + Clone, B: NewService + Clone,
{ {
fn clone(&self) -> Self { fn clone(&self) -> Self {
Self { Self {
a: self.a.clone(), a: self.a.clone(),
b: self.b.clone(), b: self.b.clone(),
_t: PhantomData,
} }
} }
} }
pub struct AndThenNewServiceFuture<A, B, C> pub struct AndThenNewServiceFuture<A, B>
where where
A: NewService<C>, A: NewService,
B: NewService<C, Request = A::Response>, B: NewService<Request = A::Response>,
{ {
fut_b: B::Future, fut_b: B::Future,
fut_a: A::Future, fut_a: A::Future,
@ -179,10 +185,10 @@ where
b: Option<B::Service>, b: Option<B::Service>,
} }
impl<A, B, C> AndThenNewServiceFuture<A, B, C> impl<A, B> AndThenNewServiceFuture<A, B>
where where
A: NewService<C>, A: NewService,
B: NewService<C, Request = A::Response>, B: NewService<Request = A::Response>,
{ {
fn new(fut_a: A::Future, fut_b: B::Future) -> Self { fn new(fut_a: A::Future, fut_b: B::Future) -> Self {
AndThenNewServiceFuture { AndThenNewServiceFuture {
@ -194,10 +200,10 @@ where
} }
} }
impl<A, B, C> Future for AndThenNewServiceFuture<A, B, C> impl<A, B> Future for AndThenNewServiceFuture<A, B>
where where
A: NewService<C>, A: NewService,
B: NewService<C, Request = A::Response, Error = A::Error, InitError = A::InitError>, B: NewService<Request = A::Response, Error = A::Error, InitError = A::InitError>,
{ {
type Item = AndThen<A::Service, B::Service>; type Item = AndThen<A::Service, B::Service>;
type Error = A::InitError; type Error = A::InitError;

View File

@ -7,17 +7,16 @@ use crate::from_err::FromErr;
use crate::{NewService, Transform}; use crate::{NewService, Transform};
/// `Apply` new service combinator /// `Apply` new service combinator
pub struct AndThenTransform<T, A, B, C> { pub struct AndThenTransform<T, A, B> {
a: A, a: A,
b: B, b: B,
t: Rc<T>, t: Rc<T>,
_t: std::marker::PhantomData<C>,
} }
impl<T, A, B, C> AndThenTransform<T, A, B, C> impl<T, A, B> AndThenTransform<T, A, B>
where where
A: NewService<C>, A: NewService,
B: NewService<C, InitError = A::InitError>, B: NewService<Config = A::Config, InitError = A::InitError>,
T: Transform<B::Service, Request = A::Response, InitError = A::InitError>, T: Transform<B::Service, Request = A::Response, InitError = A::InitError>,
T::Error: From<A::Error>, T::Error: From<A::Error>,
{ {
@ -27,12 +26,11 @@ where
a, a,
b, b,
t: Rc::new(t), t: Rc::new(t),
_t: std::marker::PhantomData,
} }
} }
} }
impl<T, A, B, C> Clone for AndThenTransform<T, A, B, C> impl<T, A, B> Clone for AndThenTransform<T, A, B>
where where
A: Clone, A: Clone,
B: Clone, B: Clone,
@ -42,15 +40,14 @@ where
a: self.a.clone(), a: self.a.clone(),
b: self.b.clone(), b: self.b.clone(),
t: self.t.clone(), t: self.t.clone(),
_t: std::marker::PhantomData,
} }
} }
} }
impl<T, A, B, C> NewService<C> for AndThenTransform<T, A, B, C> impl<T, A, B> NewService for AndThenTransform<T, A, B>
where where
A: NewService<C>, A: NewService,
B: NewService<C, InitError = A::InitError>, B: NewService<Config = A::Config, InitError = A::InitError>,
T: Transform<B::Service, Request = A::Response, InitError = A::InitError>, T: Transform<B::Service, Request = A::Response, InitError = A::InitError>,
T::Error: From<A::Error>, T::Error: From<A::Error>,
{ {
@ -58,11 +55,12 @@ where
type Response = T::Response; type Response = T::Response;
type Error = T::Error; type Error = T::Error;
type Config = A::Config;
type InitError = T::InitError; type InitError = T::InitError;
type Service = AndThen<FromErr<A::Service, T::Error>, T::Transform>; type Service = AndThen<FromErr<A::Service, T::Error>, T::Transform>;
type Future = AndThenTransformFuture<T, A, B, C>; type Future = AndThenTransformFuture<T, A, B>;
fn new_service(&self, cfg: &C) -> Self::Future { fn new_service(&self, cfg: &A::Config) -> Self::Future {
AndThenTransformFuture { AndThenTransformFuture {
a: None, a: None,
t: None, t: None,
@ -74,10 +72,10 @@ where
} }
} }
pub struct AndThenTransformFuture<T, A, B, C> pub struct AndThenTransformFuture<T, A, B>
where where
A: NewService<C>, A: NewService,
B: NewService<C, InitError = A::InitError>, B: NewService<InitError = A::InitError>,
T: Transform<B::Service, Request = A::Response, InitError = A::InitError>, T: Transform<B::Service, Request = A::Response, InitError = A::InitError>,
T::Error: From<A::Error>, T::Error: From<A::Error>,
{ {
@ -89,10 +87,10 @@ where
t_cell: Rc<T>, t_cell: Rc<T>,
} }
impl<T, A, B, C> Future for AndThenTransformFuture<T, A, B, C> impl<T, A, B> Future for AndThenTransformFuture<T, A, B>
where where
A: NewService<C>, A: NewService,
B: NewService<C, InitError = A::InitError>, B: NewService<InitError = A::InitError>,
T: Transform<B::Service, Request = A::Response, InitError = A::InitError>, T: Transform<B::Service, Request = A::Response, InitError = A::InitError>,
T::Error: From<A::Error>, T::Error: From<A::Error>,
{ {

View File

@ -133,27 +133,23 @@ where
} }
/// `ApplyNewService` new service combinator /// `ApplyNewService` new service combinator
pub struct AndThenApplyNewService<A, B, F, Out, Cfg> { pub struct AndThenApplyNewService<A, B, F, Out> {
a: A, a: A,
b: B, b: B,
f: Cell<F>, f: Cell<F>,
r: PhantomData<(Out, Cfg)>, r: PhantomData<Out>,
} }
impl<A, B, F, Out, Cfg> AndThenApplyNewService<A, B, F, Out, Cfg> impl<A, B, F, Out> AndThenApplyNewService<A, B, F, Out>
where where
A: NewService<Cfg>, A: NewService,
B: NewService<Cfg, Error = A::Error, InitError = A::InitError>, B: NewService<Config = A::Config, Error = A::Error, InitError = A::InitError>,
F: FnMut(A::Response, &mut B::Service) -> Out, F: FnMut(A::Response, &mut B::Service) -> Out,
Out: IntoFuture, Out: IntoFuture,
Out::Error: Into<A::Error>, Out::Error: Into<A::Error>,
{ {
/// Create new `ApplyNewService` new service instance /// Create new `ApplyNewService` new service instance
pub fn new<A1: IntoNewService<A, Cfg>, B1: IntoNewService<B, Cfg>>( pub fn new<A1: IntoNewService<A>, B1: IntoNewService<B>>(a: A1, b: B1, f: F) -> Self {
a: A1,
b: B1,
f: F,
) -> Self {
Self { Self {
f: Cell::new(f), f: Cell::new(f),
a: a.into_new_service(), a: a.into_new_service(),
@ -163,7 +159,7 @@ where
} }
} }
impl<A, B, F, Out, Cfg> Clone for AndThenApplyNewService<A, B, F, Out, Cfg> impl<A, B, F, Out> Clone for AndThenApplyNewService<A, B, F, Out>
where where
A: Clone, A: Clone,
B: Clone, B: Clone,
@ -178,10 +174,10 @@ where
} }
} }
impl<A, B, F, Out, Cfg> NewService<Cfg> for AndThenApplyNewService<A, B, F, Out, Cfg> impl<A, B, F, Out> NewService for AndThenApplyNewService<A, B, F, Out>
where where
A: NewService<Cfg>, A: NewService,
B: NewService<Cfg, Error = A::Error, InitError = A::InitError>, B: NewService<Config = A::Config, Error = A::Error, InitError = A::InitError>,
F: FnMut(A::Response, &mut B::Service) -> Out, F: FnMut(A::Response, &mut B::Service) -> Out,
Out: IntoFuture, Out: IntoFuture,
Out::Error: Into<A::Error>, Out::Error: Into<A::Error>,
@ -190,11 +186,11 @@ where
type Response = Out::Item; type Response = Out::Item;
type Error = A::Error; type Error = A::Error;
type Service = AndThenApply<A::Service, B::Service, F, Out>; type Service = AndThenApply<A::Service, B::Service, F, Out>;
type Config = A::Config;
type InitError = A::InitError; type InitError = A::InitError;
type Future = AndThenApplyNewServiceFuture<A, B, F, Out, Cfg>; type Future = AndThenApplyNewServiceFuture<A, B, F, Out>;
fn new_service(&self, cfg: &Cfg) -> Self::Future { fn new_service(&self, cfg: &A::Config) -> Self::Future {
AndThenApplyNewServiceFuture { AndThenApplyNewServiceFuture {
a: None, a: None,
b: None, b: None,
@ -205,10 +201,10 @@ where
} }
} }
pub struct AndThenApplyNewServiceFuture<A, B, F, Out, Cfg> pub struct AndThenApplyNewServiceFuture<A, B, F, Out>
where where
A: NewService<Cfg>, A: NewService,
B: NewService<Cfg, Error = A::Error, InitError = A::InitError>, B: NewService<Error = A::Error, InitError = A::InitError>,
F: FnMut(A::Response, &mut B::Service) -> Out, F: FnMut(A::Response, &mut B::Service) -> Out,
Out: IntoFuture, Out: IntoFuture,
Out::Error: Into<A::Error>, Out::Error: Into<A::Error>,
@ -220,10 +216,10 @@ where
b: Option<B::Service>, b: Option<B::Service>,
} }
impl<A, B, F, Out, Cfg> Future for AndThenApplyNewServiceFuture<A, B, F, Out, Cfg> impl<A, B, F, Out> Future for AndThenApplyNewServiceFuture<A, B, F, Out>
where where
A: NewService<Cfg>, A: NewService,
B: NewService<Cfg, Error = A::Error, InitError = A::InitError>, B: NewService<Error = A::Error, InitError = A::InitError>,
F: FnMut(A::Response, &mut B::Service) -> Out, F: FnMut(A::Response, &mut B::Service) -> Out,
Out: IntoFuture, Out: IntoFuture,
Out::Error: Into<A::Error>, Out::Error: Into<A::Error>,

View File

@ -16,17 +16,14 @@ where
Apply::new(service.into_service(), f) Apply::new(service.into_service(), f)
} }
/// Create fractory for `apply_fn` service. /// Create factory for `apply` service.
pub fn apply_fn_factory<T, F, In, Out, Cfg, U>( pub fn new_apply_fn<T, F, In, Out, U>(service: U, f: F) -> ApplyNewService<T, F, In, Out>
service: U,
f: F,
) -> ApplyNewService<T, F, In, Out, Cfg>
where where
T: NewService<Cfg>, T: NewService,
F: FnMut(In, &mut T::Service) -> Out + Clone, F: FnMut(In, &mut T::Service) -> Out + Clone,
Out: IntoFuture, Out: IntoFuture,
Out::Error: From<T::Error>, Out::Error: From<T::Error>,
U: IntoNewService<T, Cfg>, U: IntoNewService<T>,
{ {
ApplyNewService::new(service.into_new_service(), f) ApplyNewService::new(service.into_new_service(), f)
} }
@ -50,7 +47,7 @@ where
Out::Error: From<T::Error>, Out::Error: From<T::Error>,
{ {
/// Create new `Apply` combinator /// Create new `Apply` combinator
pub fn new<I: IntoService<T>>(service: I, f: F) -> Self { pub(crate) fn new<I: IntoService<T>>(service: I, f: F) -> Self {
Self { Self {
service: service.into_service(), service: service.into_service(),
f, f,
@ -95,24 +92,24 @@ where
} }
/// `ApplyNewService` new service combinator /// `ApplyNewService` new service combinator
pub struct ApplyNewService<T, F, In, Out, Cfg> pub struct ApplyNewService<T, F, In, Out>
where where
T: NewService<Cfg>, T: NewService,
{ {
service: T, service: T,
f: F, f: F,
r: PhantomData<(In, Out, Cfg)>, r: PhantomData<(In, Out)>,
} }
impl<T, F, In, Out, Cfg> ApplyNewService<T, F, In, Out, Cfg> impl<T, F, In, Out> ApplyNewService<T, F, In, Out>
where where
T: NewService<Cfg>, T: NewService,
F: FnMut(In, &mut T::Service) -> Out + Clone, F: FnMut(In, &mut T::Service) -> Out + Clone,
Out: IntoFuture, Out: IntoFuture,
Out::Error: From<T::Error>, Out::Error: From<T::Error>,
{ {
/// Create new `ApplyNewService` new service instance /// Create new `ApplyNewService` new service instance
pub fn new<F1: IntoNewService<T, Cfg>>(service: F1, f: F) -> Self { pub(crate) fn new<F1: IntoNewService<T>>(service: F1, f: F) -> Self {
Self { Self {
f, f,
service: service.into_new_service(), service: service.into_new_service(),
@ -121,9 +118,9 @@ where
} }
} }
impl<T, F, In, Out, Cfg> Clone for ApplyNewService<T, F, In, Out, Cfg> impl<T, F, In, Out> Clone for ApplyNewService<T, F, In, Out>
where where
T: NewService<Cfg> + Clone, T: NewService + Clone,
F: FnMut(In, &mut T::Service) -> Out + Clone, F: FnMut(In, &mut T::Service) -> Out + Clone,
Out: IntoFuture, Out: IntoFuture,
{ {
@ -136,9 +133,9 @@ where
} }
} }
impl<T, F, In, Out, Cfg> NewService<Cfg> for ApplyNewService<T, F, In, Out, Cfg> impl<T, F, In, Out> NewService for ApplyNewService<T, F, In, Out>
where where
T: NewService<Cfg>, T: NewService,
F: FnMut(In, &mut T::Service) -> Out + Clone, F: FnMut(In, &mut T::Service) -> Out + Clone,
Out: IntoFuture, Out: IntoFuture,
Out::Error: From<T::Error>, Out::Error: From<T::Error>,
@ -146,19 +143,20 @@ where
type Request = In; type Request = In;
type Response = Out::Item; type Response = Out::Item;
type Error = Out::Error; type Error = Out::Error;
type Config = T::Config;
type Service = Apply<T::Service, F, In, Out>; type Service = Apply<T::Service, F, In, Out>;
type InitError = T::InitError; type InitError = T::InitError;
type Future = ApplyNewServiceFuture<T, F, In, Out, Cfg>; type Future = ApplyNewServiceFuture<T, F, In, Out>;
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()) ApplyNewServiceFuture::new(self.service.new_service(cfg), self.f.clone())
} }
} }
pub struct ApplyNewServiceFuture<T, F, In, Out, Cfg> pub struct ApplyNewServiceFuture<T, F, In, Out>
where where
T: NewService<Cfg>, T: NewService,
F: FnMut(In, &mut T::Service) -> Out + Clone, F: FnMut(In, &mut T::Service) -> Out + Clone,
Out: IntoFuture, Out: IntoFuture,
{ {
@ -167,9 +165,9 @@ where
r: PhantomData<(In, Out)>, r: PhantomData<(In, Out)>,
} }
impl<T, F, In, Out, Cfg> ApplyNewServiceFuture<T, F, In, Out, Cfg> impl<T, F, In, Out> ApplyNewServiceFuture<T, F, In, Out>
where where
T: NewService<Cfg>, T: NewService,
F: FnMut(In, &mut T::Service) -> Out + Clone, F: FnMut(In, &mut T::Service) -> Out + Clone,
Out: IntoFuture, Out: IntoFuture,
{ {
@ -182,9 +180,9 @@ where
} }
} }
impl<T, F, In, Out, Cfg> Future for ApplyNewServiceFuture<T, F, In, Out, Cfg> impl<T, F, In, Out> Future for ApplyNewServiceFuture<T, F, In, Out>
where where
T: NewService<Cfg>, T: NewService,
F: FnMut(In, &mut T::Service) -> Out + Clone, F: FnMut(In, &mut T::Service) -> Out + Clone,
Out: IntoFuture, Out: IntoFuture,
Out::Error: From<T::Error>, Out::Error: From<T::Error>,

View File

@ -1,112 +1,104 @@
use std::marker::PhantomData; 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 use crate::cell::Cell;
pub fn apply_cfg<F, S, C1, C2, U>(f: F, service: U) -> ApplyConfig<F, S, C1, C2> use crate::{IntoService, NewService, Service};
/// Convert `Fn(&Config, &mut Service) -> Future<Service>` fn to a NewService
pub fn apply_cfg<F, C, T, R, S>(srv: T, f: F) -> ApplyConfigService<F, C, T, R, S>
where where
S: NewService<C2>, F: FnMut(&C, &mut T) -> R,
F: Fn(&C1) -> C2, T: Service,
U: IntoNewService<S, C2>, R: IntoFuture,
R::Item: IntoService<S>,
S: Service,
{ {
ApplyConfig::new(service.into_new_service(), f) ApplyConfigService {
} f: Cell::new(f),
srv: Cell::new(srv.into_service()),
/// `ApplyConfig` service factory combinator _t: PhantomData,
pub struct ApplyConfig<F, S, C1, C2> {
s: S,
f: F,
r: PhantomData<(C1, C2)>,
}
impl<F, S, C1, C2> ApplyConfig<F, S, C1, C2>
where
S: NewService<C2>,
F: Fn(&C1) -> C2,
{
/// Create new ApplyConfig` service factory combinator
pub fn new<U: IntoNewService<S, C2>>(a: U, f: F) -> Self {
Self {
f,
s: a.into_new_service(),
r: PhantomData,
}
} }
} }
impl<F, S, C1, C2> Clone for ApplyConfig<F, S, C1, C2> /// Convert `Fn(&Config) -> Future<Service>` fn to NewService
pub struct ApplyConfigService<F, C, T, R, S>
where where
S: Clone, F: FnMut(&C, &mut T) -> R,
F: Clone, T: Service,
R: IntoFuture,
R::Item: IntoService<S>,
S: Service,
{
f: Cell<F>,
srv: Cell<T>,
_t: PhantomData<(C, R, S)>,
}
impl<F, C, T, R, S> Clone for ApplyConfigService<F, C, T, R, S>
where
F: FnMut(&C, &mut T) -> R,
T: Service,
R: IntoFuture,
R::Item: IntoService<S>,
S: Service,
{ {
fn clone(&self) -> Self { fn clone(&self) -> Self {
Self { ApplyConfigService {
s: self.s.clone(),
f: self.f.clone(), f: self.f.clone(),
r: PhantomData, srv: self.srv.clone(),
_t: PhantomData,
} }
} }
} }
impl<F, S, C1, C2> NewService<C1> for ApplyConfig<F, S, C1, C2> impl<F, C, T, R, S> NewService for ApplyConfigService<F, C, T, R, S>
where where
S: NewService<C2>, F: FnMut(&C, &mut T) -> R,
F: Fn(&C1) -> C2, T: Service,
R: IntoFuture,
R::Item: IntoService<S>,
S: Service,
{ {
type Config = C;
type Request = S::Request; type Request = S::Request;
type Response = S::Response; type Response = S::Response;
type Error = S::Error; type Error = S::Error;
type Service = S::Service; type Service = S;
type InitError = S::InitError; type InitError = R::Error;
type Future = S::Future; type Future = FnNewServiceConfigFut<R, S>;
fn new_service(&self, cfg: &C1) -> Self::Future { fn new_service(&self, cfg: &C) -> Self::Future {
let cfg2 = (self.f)(cfg); FnNewServiceConfigFut {
fut: unsafe { (self.f.get_mut_unsafe())(cfg, self.srv.get_mut_unsafe()) }
self.s.new_service(&cfg2) .into_future(),
} _t: PhantomData,
}
#[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());
} }
} }
} }
pub struct FnNewServiceConfigFut<R, S>
where
R: IntoFuture,
R::Item: IntoService<S>,
S: Service,
{
fut: R::Future,
_t: PhantomData<(S,)>,
}
impl<R, S> Future for FnNewServiceConfigFut<R, S>
where
R: IntoFuture,
R::Item: IntoService<S>,
S: Service,
{
type Item = S;
type Error = R::Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
Ok(Async::Ready(try_ready!(self.fut.poll()).into_service()))
}
}

View File

@ -68,12 +68,13 @@ impl<R, E1, E2> Default for BlankNewService<R, E1, E2> {
} }
} }
impl<R, E1, E2> NewService<()> for BlankNewService<R, E1, E2> { impl<R, E1, E2> NewService for BlankNewService<R, E1, E2> {
type Request = R; type Request = R;
type Response = R; type Response = R;
type Error = E1; type Error = E1;
type Service = Blank<R, E1>;
type Config = ();
type Service = Blank<R, E1>;
type InitError = E2; type InitError = E2;
type Future = FutureResult<Self::Service, Self::InitError>; type Future = FutureResult<Self::Service, Self::InitError>;

View File

@ -15,13 +15,14 @@ pub type BoxedService<Req, Res, Err> = Box<
pub type BoxedServiceResponse<Res, Err> = pub type BoxedServiceResponse<Res, Err> =
Either<FutureResult<Res, Err>, Box<Future<Item = Res, Error = Err>>>; Either<FutureResult<Res, Err>, Box<Future<Item = Res, Error = Err>>>;
pub struct BoxedNewService<C, Req, Res, Err, InitErr>(Inner<C, Req, Res, Err, InitErr>);
/// Create boxed new service /// Create boxed new service
pub fn new_service<T, C>( pub fn new_service<T>(
service: T, service: T,
) -> BoxedNewService<C, T::Request, T::Response, T::Error, T::InitError> ) -> BoxedNewService<T::Config, T::Request, T::Response, T::Error, T::InitError>
where where
C: 'static, T: NewService + 'static,
T: NewService<C> + 'static,
T::Request: 'static, T::Request: 'static,
T::Response: 'static, T::Response: 'static,
T::Service: 'static, T::Service: 'static,
@ -46,7 +47,7 @@ where
type Inner<C, Req, Res, Err, InitErr> = Box< type Inner<C, Req, Res, Err, InitErr> = Box<
NewService< NewService<
C, Config = C,
Request = Req, Request = Req,
Response = Res, Response = Res,
Error = Err, Error = Err,
@ -56,9 +57,7 @@ type Inner<C, Req, Res, Err, InitErr> = Box<
>, >,
>; >;
pub struct BoxedNewService<C, Req, Res, Err, InitErr>(Inner<C, Req, Res, Err, InitErr>); impl<C, Req, Res, Err, InitErr> NewService for BoxedNewService<C, Req, Res, Err, InitErr>
impl<C, Req, Res, Err, InitErr> NewService<C> for BoxedNewService<C, Req, Res, Err, InitErr>
where where
Req: 'static, Req: 'static,
Res: 'static, Res: 'static,
@ -69,6 +68,7 @@ where
type Response = Res; type Response = Res;
type Error = Err; type Error = Err;
type InitError = InitErr; type InitError = InitErr;
type Config = C;
type Service = BoxedService<Req, Res, Err>; type Service = BoxedService<Req, Res, Err>;
type Future = Box<Future<Item = Self::Service, Error = Self::InitError>>; type Future = Box<Future<Item = Self::Service, Error = Self::InitError>>;
@ -77,18 +77,18 @@ where
} }
} }
struct NewServiceWrapper<C, T: NewService<C>> { struct NewServiceWrapper<C, T: NewService> {
service: T, service: T,
_t: std::marker::PhantomData<C>, _t: std::marker::PhantomData<C>,
} }
impl<C, T, Req, Res, Err, InitErr> NewService<C> for NewServiceWrapper<C, T> impl<C, T, Req, Res, Err, InitErr> NewService for NewServiceWrapper<C, T>
where where
Req: 'static, Req: 'static,
Res: 'static, Res: 'static,
Err: 'static, Err: 'static,
InitErr: 'static, InitErr: 'static,
T: NewService<C, Request = Req, Response = Res, Error = Err, InitError = InitErr>, T: NewService<Config = C, Request = Req, Response = Res, Error = Err, InitError = InitErr>,
T::Future: 'static, T::Future: 'static,
T::Service: 'static, T::Service: 'static,
<T::Service as Service>::Future: 'static, <T::Service as Service>::Future: 'static,
@ -97,6 +97,7 @@ where
type Response = Res; type Response = Res;
type Error = Err; type Error = Err;
type InitError = InitErr; type InitError = InitErr;
type Config = C;
type Service = BoxedService<Req, Res, Err>; type Service = BoxedService<Req, Res, Err>;
type Future = Box<Future<Item = Self::Service, Error = Self::InitError>>; type Future = Box<Future<Item = Self::Service, Error = Self::InitError>>;

View File

@ -29,4 +29,8 @@ impl<T> Cell<T> {
pub(crate) fn get_mut(&mut self) -> &mut T { pub(crate) fn get_mut(&mut self) -> &mut T {
unsafe { &mut *self.inner.as_ref().get() } unsafe { &mut *self.inner.as_ref().get() }
} }
pub(crate) unsafe fn get_mut_unsafe(&self) -> &mut T {
&mut *self.inner.as_ref().get()
}
} }

View File

@ -3,29 +3,30 @@ use std::marker::PhantomData;
use futures::future::{ok, Future, FutureResult}; use futures::future::{ok, Future, FutureResult};
use futures::{try_ready, Async, IntoFuture, Poll}; 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 /// Create `NewService` for function that can act as a Service
pub fn fn_service<F, Req, Out, Cfg>(f: F) -> FnNewService<F, Req, Out, Cfg> pub fn service_fn<F, Req, Out, Cfg>(f: F) -> NewServiceFn<F, Req, Out, Cfg>
where where
F: FnMut(Req) -> Out + Clone, F: FnMut(Req) -> Out + Clone,
Out: IntoFuture, Out: IntoFuture,
{ {
FnNewService::new(f) NewServiceFn::new(f)
} }
/// Create `NewService` for function that can produce services /// Create `NewService` for function that can produce services
pub fn fn_factory<F, R, S, E>(f: F) -> FnNewServiceNoConfig<F, R, S, E> pub fn new_service_fn<F, C, R, S, E>(f: F) -> FnNewServiceNoConfig<F, C, R, S, E>
where where
F: Fn() -> R, F: Fn() -> R,
R: IntoFuture<Item = S, Error = E>, R: IntoFuture<Item = S, Error = E>,
R::Item: IntoService<S>,
S: Service, S: Service,
{ {
FnNewServiceNoConfig::new(f) FnNewServiceNoConfig::new(f)
} }
/// Create `NewService` for function that can produce services with configuration /// Create `NewService` for function that can produce services with configuration
pub fn fn_cfg_factory<F, C, R, S, E>(f: F) -> FnNewServiceConfig<F, C, R, S, E> pub fn new_service_cfg<F, C, R, S, E>(f: F) -> FnNewServiceConfig<F, C, R, S, E>
where where
F: Fn(&C) -> R, F: Fn(&C) -> R,
R: IntoFuture<Error = E>, R: IntoFuture<Error = E>,
@ -35,39 +36,36 @@ where
FnNewServiceConfig::new(f) FnNewServiceConfig::new(f)
} }
pub struct FnService<F, Req, Out> pub struct ServiceFn<F, Req, Out>
where where
F: FnMut(Req) -> Out, F: FnMut(Req) -> Out,
Out: IntoFuture, Out: IntoFuture,
{ {
f: F, f: F,
_t: PhantomData<(Req,)>, _t: PhantomData<Req>,
} }
impl<F, Req, Out> FnService<F, Req, Out> impl<F, Req, Out> ServiceFn<F, Req, Out>
where where
F: FnMut(Req) -> Out, F: FnMut(Req) -> Out,
Out: IntoFuture, Out: IntoFuture,
{ {
pub fn new(f: F) -> Self { pub(crate) fn new(f: F) -> Self {
FnService { f, _t: PhantomData } ServiceFn { f, _t: PhantomData }
} }
} }
impl<F, Req, Out> Clone for FnService<F, Req, Out> impl<F, Req, Out> Clone for ServiceFn<F, Req, Out>
where where
F: FnMut(Req) -> Out + Clone, F: FnMut(Req) -> Out + Clone,
Out: IntoFuture, Out: IntoFuture,
{ {
fn clone(&self) -> Self { fn clone(&self) -> Self {
FnService { ServiceFn::new(self.f.clone())
f: self.f.clone(),
_t: PhantomData,
}
} }
} }
impl<F, Req, Out> Service for FnService<F, Req, Out> impl<F, Req, Out> Service for ServiceFn<F, Req, Out>
where where
F: FnMut(Req) -> Out, F: FnMut(Req) -> Out,
Out: IntoFuture, Out: IntoFuture,
@ -86,17 +84,17 @@ where
} }
} }
impl<F, Req, Out> IntoService<FnService<F, Req, Out>> for F impl<F, Req, Out> IntoService<ServiceFn<F, Req, Out>> for F
where where
F: FnMut(Req) -> Out + 'static, F: FnMut(Req) -> Out,
Out: IntoFuture, Out: IntoFuture,
{ {
fn into_service(self) -> FnService<F, Req, Out> { fn into_service(self) -> ServiceFn<F, Req, Out> {
FnService::new(self) ServiceFn::new(self)
} }
} }
pub struct FnNewService<F, Req, Out, Cfg> pub struct NewServiceFn<F, Req, Out, Cfg>
where where
F: FnMut(Req) -> Out, F: FnMut(Req) -> Out,
Out: IntoFuture, Out: IntoFuture,
@ -105,17 +103,27 @@ where
_t: PhantomData<(Req, Cfg)>, _t: PhantomData<(Req, Cfg)>,
} }
impl<F, Req, Out, Cfg> FnNewService<F, Req, Out, Cfg> impl<F, Req, Out, Cfg> NewServiceFn<F, Req, Out, Cfg>
where where
F: FnMut(Req) -> Out + Clone, F: FnMut(Req) -> Out + Clone,
Out: IntoFuture, Out: IntoFuture,
{ {
pub fn new(f: F) -> Self { pub(crate) fn new(f: F) -> Self {
FnNewService { f, _t: PhantomData } NewServiceFn { f, _t: PhantomData }
} }
} }
impl<F, Req, Out, Cfg> NewService<Cfg> for FnNewService<F, Req, Out, Cfg> impl<F, Req, Out, Cfg> Clone for NewServiceFn<F, Req, Out, Cfg>
where
F: FnMut(Req) -> Out + Clone,
Out: IntoFuture,
{
fn clone(&self) -> Self {
NewServiceFn::new(self.f.clone())
}
}
impl<F, Req, Out, Cfg> NewService for NewServiceFn<F, Req, Out, Cfg>
where where
F: FnMut(Req) -> Out + Clone, F: FnMut(Req) -> Out + Clone,
Out: IntoFuture, Out: IntoFuture,
@ -123,95 +131,34 @@ where
type Request = Req; type Request = Req;
type Response = Out::Item; type Response = Out::Item;
type Error = Out::Error; type Error = Out::Error;
type Service = FnService<F, Req, Out>;
type Config = Cfg;
type Service = ServiceFn<F, Req, Out>;
type InitError = (); type InitError = ();
type Future = FutureResult<Self::Service, Self::InitError>; type Future = FutureResult<Self::Service, Self::InitError>;
fn new_service(&self, _: &Cfg) -> Self::Future { fn new_service(&self, _: &Cfg) -> Self::Future {
ok(FnService::new(self.f.clone())) ok(ServiceFn::new(self.f.clone()))
} }
} }
impl<F, Req, Out, Cfg> Clone for FnNewService<F, Req, Out, Cfg> impl<F, Req, Out, Cfg> IntoService<ServiceFn<F, Req, Out>> for NewServiceFn<F, Req, Out, Cfg>
where where
F: FnMut(Req) -> Out + Clone, F: FnMut(Req) -> Out + Clone,
Out: IntoFuture, Out: IntoFuture,
{ {
fn clone(&self) -> Self { fn into_service(self) -> ServiceFn<F, Req, Out> {
Self::new(self.f.clone()) ServiceFn::new(self.f.clone())
} }
} }
impl<F, Req, Out, Cfg> IntoNewService<FnNewService<F, Req, Out, Cfg>, Cfg> for F impl<F, Req, Out, Cfg> IntoNewService<NewServiceFn<F, Req, Out, Cfg>> for F
where where
F: Fn(Req) -> Out + Clone, F: Fn(Req) -> Out + Clone,
Out: IntoFuture, Out: IntoFuture,
{ {
fn into_new_service(self) -> FnNewService<F, Req, Out, Cfg> { fn into_new_service(self) -> NewServiceFn<F, Req, Out, Cfg> {
FnNewService::new(self) NewServiceFn::new(self)
}
}
/// Converter for `Fn() -> Future<Service>` fn
pub struct FnNewServiceNoConfig<F, R, S, E>
where
F: Fn() -> R,
R: IntoFuture<Item = S, Error = E>,
S: Service,
{
f: F,
}
impl<F, R, S, E> FnNewServiceNoConfig<F, R, S, E>
where
F: Fn() -> R,
R: IntoFuture<Item = S, Error = E>,
S: Service,
{
pub fn new(f: F) -> Self {
FnNewServiceNoConfig { f }
}
}
impl<F, R, S, E> NewService<()> for FnNewServiceNoConfig<F, R, S, E>
where
F: Fn() -> R,
R: IntoFuture<Item = S, Error = E>,
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<F, R, S, E> Clone for FnNewServiceNoConfig<F, R, S, E>
where
F: Fn() -> R + Clone,
R: IntoFuture<Item = S, Error = E>,
S: Service,
{
fn clone(&self) -> Self {
Self::new(self.f.clone())
}
}
impl<F, R, S, E> IntoNewService<FnNewServiceNoConfig<F, R, S, E>, ()> for F
where
F: Fn() -> R,
R: IntoFuture<Item = S, Error = E>,
S: Service,
{
fn into_new_service(self) -> FnNewServiceNoConfig<F, R, S, E> {
FnNewServiceNoConfig::new(self)
} }
} }
@ -239,7 +186,7 @@ where
} }
} }
impl<F, C, R, S, E> NewService<C> for FnNewServiceConfig<F, C, R, S, E> impl<F, C, R, S, E> NewService for FnNewServiceConfig<F, C, R, S, E>
where where
F: Fn(&C) -> R, F: Fn(&C) -> R,
R: IntoFuture<Error = E>, R: IntoFuture<Error = E>,
@ -249,8 +196,9 @@ where
type Request = S::Request; type Request = S::Request;
type Response = S::Response; type Response = S::Response;
type Error = S::Error; type Error = S::Error;
type Service = S;
type Config = C;
type Service = S;
type InitError = E; type InitError = E;
type Future = FnNewServiceConfigFut<R, S, E>; type Future = FnNewServiceConfigFut<R, S, E>;
@ -298,14 +246,65 @@ where
} }
} }
impl<F, C, R, S, E> IntoConfigurableNewService<FnNewServiceConfig<F, C, R, S, E>, C> for F /// Converter for `Fn() -> Future<Service>` fn
pub struct FnNewServiceNoConfig<F, C, R, S, E>
where where
F: Fn(&C) -> R, F: Fn() -> R,
R: IntoFuture<Error = E>, R: IntoFuture<Item = S, Error = E>,
R::Item: IntoService<S>,
S: Service, S: Service,
{ {
fn into_new_service(self) -> FnNewServiceConfig<F, C, R, S, E> { f: F,
FnNewServiceConfig::new(self) _t: PhantomData<C>,
}
impl<F, C, R, S, E> FnNewServiceNoConfig<F, C, R, S, E>
where
F: Fn() -> R,
R: IntoFuture<Item = S, Error = E>,
S: Service,
{
pub fn new(f: F) -> Self {
FnNewServiceNoConfig { f, _t: PhantomData }
}
}
impl<F, C, R, S, E> NewService for FnNewServiceNoConfig<F, C, R, S, E>
where
F: Fn() -> R,
R: IntoFuture<Item = S, Error = E>,
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<F, C, R, S, E> Clone for FnNewServiceNoConfig<F, C, R, S, E>
where
F: Fn() -> R + Clone,
R: IntoFuture<Item = S, Error = E>,
S: Service,
{
fn clone(&self) -> Self {
Self::new(self.f.clone())
}
}
impl<F, C, R, S, E> IntoNewService<FnNewServiceNoConfig<F, C, R, S, E>> for F
where
F: Fn() -> R,
R: IntoFuture<Item = S, Error = E>,
S: Service,
{
fn into_new_service(self) -> FnNewServiceNoConfig<F, C, R, S, E> {
FnNewServiceNoConfig::new(self)
} }
} }

View File

@ -3,10 +3,11 @@ use std::marker::PhantomData;
use futures::future::{ok, FutureResult}; use futures::future::{ok, FutureResult};
use futures::IntoFuture; use futures::IntoFuture;
use crate::{Apply, IntoTransform, Service, Transform}; use crate::apply::Apply;
use crate::{IntoTransform, Service, Transform};
/// Use function as transform service /// Use function as transform service
pub fn fn_transform<F, S, In, Out, Err>( pub fn transform_fn<F, S, In, Out, Err>(
f: F, f: F,
) -> impl Transform<S, Request = In, Response = Out::Item, Error = Out::Error, InitError = Err> ) -> impl Transform<S, Request = In, Response = Out::Item, Error = Out::Error, InitError = Err>
where where

View File

@ -81,23 +81,23 @@ where
/// service's error. /// service's error.
/// ///
/// This is created by the `NewServiceExt::from_err` method. /// This is created by the `NewServiceExt::from_err` method.
pub struct FromErrNewService<A, E, C> { pub struct FromErrNewService<A, E> {
a: A, a: A,
e: PhantomData<(E, C)>, e: PhantomData<E>,
} }
impl<A, E, C> FromErrNewService<A, E, C> { impl<A, E> FromErrNewService<A, E> {
/// Create new `FromErr` new service instance /// Create new `FromErr` new service instance
pub fn new(a: A) -> Self pub fn new(a: A) -> Self
where where
A: NewService<C>, A: NewService,
E: From<A::Error>, E: From<A::Error>,
{ {
Self { a, e: PhantomData } Self { a, e: PhantomData }
} }
} }
impl<A, E, C> Clone for FromErrNewService<A, E, C> impl<A, E> Clone for FromErrNewService<A, E>
where where
A: Clone, A: Clone,
{ {
@ -109,20 +109,21 @@ where
} }
} }
impl<A, E, C> NewService<C> for FromErrNewService<A, E, C> impl<A, E> NewService for FromErrNewService<A, E>
where where
A: NewService<C>, A: NewService,
E: From<A::Error>, E: From<A::Error>,
{ {
type Request = A::Request; type Request = A::Request;
type Response = A::Response; type Response = A::Response;
type Error = E; type Error = E;
type Config = A::Config;
type Service = FromErr<A::Service, E>; type Service = FromErr<A::Service, E>;
type InitError = A::InitError; type InitError = A::InitError;
type Future = FromErrNewServiceFuture<A, E, C>; type Future = FromErrNewServiceFuture<A, E>;
fn new_service(&self, cfg: &C) -> Self::Future { fn new_service(&self, cfg: &A::Config) -> Self::Future {
FromErrNewServiceFuture { FromErrNewServiceFuture {
fut: self.a.new_service(cfg), fut: self.a.new_service(cfg),
e: PhantomData, e: PhantomData,
@ -130,18 +131,18 @@ where
} }
} }
pub struct FromErrNewServiceFuture<A, E, C> pub struct FromErrNewServiceFuture<A, E>
where where
A: NewService<C>, A: NewService,
E: From<A::Error>, E: From<A::Error>,
{ {
fut: A::Future, fut: A::Future,
e: PhantomData<E>, e: PhantomData<E>,
} }
impl<A, E, C> Future for FromErrNewServiceFuture<A, E, C> impl<A, E> Future for FromErrNewServiceFuture<A, E>
where where
A: NewService<C>, A: NewService,
E: From<A::Error>, E: From<A::Error>,
{ {
type Item = FromErr<A::Service, E>; type Item = FromErr<A::Service, E>;

View File

@ -4,8 +4,6 @@ use std::sync::Arc;
use futures::{Future, IntoFuture, Poll}; use futures::{Future, IntoFuture, Poll};
pub use void::Void;
mod and_then; mod and_then;
mod and_then_apply; mod and_then_apply;
mod and_then_apply_fn; mod and_then_apply_fn;
@ -18,40 +16,29 @@ mod fn_service;
mod fn_transform; mod fn_transform;
mod from_err; mod from_err;
mod map; mod map;
mod map_config;
mod map_err; mod map_err;
mod map_init_err; mod map_init_err;
mod then; mod then;
mod transform; mod transform;
mod transform_err; 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}; pub use self::and_then::{AndThen, AndThenNewService};
use self::and_then_apply::AndThenTransform; pub use self::apply::{apply_fn, new_apply_fn, Apply, ApplyNewService};
use self::and_then_apply_fn::{AndThenApply, AndThenApplyNewService};
pub use self::apply::{apply_fn, apply_fn_factory};
pub use self::apply_cfg::apply_cfg; pub use self::apply_cfg::apply_cfg;
use self::apply_cfg::ApplyConfig; pub use self::fn_service::{new_service_cfg, new_service_fn, service_fn, ServiceFn};
pub use self::fn_service::{fn_cfg_factory, fn_factory, fn_service, FnService}; pub use self::fn_transform::transform_fn;
pub use self::fn_transform::fn_transform;
pub use self::from_err::{FromErr, FromErrNewService}; pub use self::from_err::{FromErr, FromErrNewService};
pub use self::map::{Map, MapNewService}; 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_err::{MapErr, MapErrNewService};
pub use self::map_init_err::MapInitErr; pub use self::map_init_err::MapInitErr;
pub use self::then::{Then, ThenNewService}; pub use self::then::{Then, ThenNewService};
pub use self::transform::{apply_transform, IntoTransform, Transform}; 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`. /// An asynchronous function from `Request` to a `Response`.
pub trait Service { pub trait Service {
/// Requests handled by the service. /// Requests handled by the service.
@ -195,7 +182,7 @@ impl<T: ?Sized> ServiceExt for T where T: Service {}
/// requests on that new TCP stream. /// requests on that new TCP stream.
/// ///
/// `Config` is a service factory configuration type. /// `Config` is a service factory configuration type.
pub trait NewService<Config = ()> { pub trait NewService {
/// Requests handled by the service. /// Requests handled by the service.
type Request; type Request;
@ -205,6 +192,9 @@ pub trait NewService<Config = ()> {
/// Errors produced by the service /// Errors produced by the service
type Error; type Error;
/// Service factory configuration
type Config;
/// The `Service` value created by this factory /// The `Service` value created by this factory
type Service: Service< type Service: Service<
Request = Self::Request, Request = Self::Request,
@ -219,37 +209,29 @@ pub trait NewService<Config = ()> {
type Future: Future<Item = Self::Service, Error = Self::InitError>; type Future: Future<Item = Self::Service, Error = Self::InitError>;
/// Create and return a new service value asynchronously. /// 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 /// Apply transform service to specified service and use it as a next service in
/// chain. /// chain.
fn apply<T, T1, B, B1>( fn apply<T, T1, B, B1>(self, transform: T1, service: B1) -> AndThenTransform<T, Self, B>
self,
transform: T1,
service: B1,
) -> AndThenTransform<T, Self, B, Config>
where where
Self: Sized, Self: Sized,
T: Transform<B::Service, Request = Self::Response, InitError = Self::InitError>, T: Transform<B::Service, Request = Self::Response, InitError = Self::InitError>,
T::Error: From<Self::Error>, T::Error: From<Self::Error>,
T1: IntoTransform<T, B::Service>, T1: IntoTransform<T, B::Service>,
B: NewService<Config, InitError = Self::InitError>, B: NewService<Config = Self::Config, InitError = Self::InitError>,
B1: IntoNewService<B, Config>, B1: IntoNewService<B>,
{ {
AndThenTransform::new(transform.into_transform(), self, service.into_new_service()) AndThenTransform::new(transform.into_transform(), self, service.into_new_service())
} }
/// Apply function to specified service and use it as a next service in /// Apply function to specified service and use it as a next service in
/// chain. /// chain.
fn apply_fn<B, I, F, Out>( fn apply_fn<B, I, F, Out>(self, service: I, f: F) -> AndThenApplyNewService<Self, B, F, Out>
self,
service: I,
f: F,
) -> AndThenApplyNewService<Self, B, F, Out, Config>
where where
Self: Sized, Self: Sized,
B: NewService<Config, Error = Self::Error, InitError = Self::InitError>, B: NewService<Config = Self::Config, Error = Self::Error, InitError = Self::InitError>,
I: IntoNewService<B, Config>, I: IntoNewService<B>,
F: FnMut(Self::Response, &mut B::Service) -> Out, F: FnMut(Self::Response, &mut B::Service) -> Out,
Out: IntoFuture, Out: IntoFuture,
Out::Error: Into<Self::Error>, Out::Error: Into<Self::Error>,
@ -257,34 +239,13 @@ pub trait NewService<Config = ()> {
AndThenApplyNewService::new(self, service, f) AndThenApplyNewService::new(self, service, f)
} }
/// Map this service's config type to a different config,
/// and use for nested service
fn apply_cfg<F, C, S, U>(
self,
service: U,
f: F,
) -> AndThenNewService<Self, ApplyConfig<F, S, Config, C>, Config>
where
Self: Sized,
F: Fn(&Config) -> C,
U: IntoNewService<S, C>,
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. /// Call another service after call to this one has resolved successfully.
fn and_then<F, B>(self, new_service: F) -> AndThenNewService<Self, B, Config> fn and_then<F, B>(self, new_service: F) -> AndThenNewService<Self, B>
where where
Self: Sized, Self: Sized,
F: IntoNewService<B, Config>, F: IntoNewService<B>,
B: NewService< B: NewService<
Config, Config = Self::Config,
Request = Self::Response, Request = Self::Response,
Error = Self::Error, Error = Self::Error,
InitError = Self::InitError, InitError = Self::InitError,
@ -299,7 +260,7 @@ pub trait NewService<Config = ()> {
/// ///
/// Note that this function consumes the receiving new service and returns a /// Note that this function consumes the receiving new service and returns a
/// wrapped version of it. /// wrapped version of it.
fn from_err<E>(self) -> FromErrNewService<Self, E, Config> fn from_err<E>(self) -> FromErrNewService<Self, E>
where where
Self: Sized, Self: Sized,
E: From<Self::Error>, E: From<Self::Error>,
@ -313,12 +274,12 @@ pub trait NewService<Config = ()> {
/// ///
/// Note that this function consumes the receiving future and returns a /// Note that this function consumes the receiving future and returns a
/// wrapped version of it. /// wrapped version of it.
fn then<F, B>(self, new_service: F) -> ThenNewService<Self, B, Config> fn then<F, B>(self, new_service: F) -> ThenNewService<Self, B>
where where
Self: Sized, Self: Sized,
F: IntoNewService<B, Config>, F: IntoNewService<B>,
B: NewService< B: NewService<
Config, Config = Self::Config,
Request = Result<Self::Response, Self::Error>, Request = Result<Self::Response, Self::Error>,
Error = Self::Error, Error = Self::Error,
InitError = Self::InitError, InitError = Self::InitError,
@ -329,7 +290,7 @@ pub trait NewService<Config = ()> {
/// Map this service's output to a different type, returning a new service /// Map this service's output to a different type, returning a new service
/// of the resulting type. /// of the resulting type.
fn map<F, R>(self, f: F) -> MapNewService<Self, F, R, Config> fn map<F, R>(self, f: F) -> MapNewService<Self, F, R>
where where
Self: Sized, Self: Sized,
F: FnMut(Self::Response) -> R, F: FnMut(Self::Response) -> R,
@ -338,7 +299,7 @@ pub trait NewService<Config = ()> {
} }
/// Map this service's error to a different error, returning a new service. /// Map this service's error to a different error, returning a new service.
fn map_err<F, E>(self, f: F) -> MapErrNewService<Self, F, E, Config> fn map_err<F, E>(self, f: F) -> MapErrNewService<Self, F, E>
where where
Self: Sized, Self: Sized,
F: Fn(Self::Error) -> E + Clone, F: Fn(Self::Error) -> E + Clone,
@ -346,14 +307,31 @@ pub trait NewService<Config = ()> {
MapErrNewService::new(self, f) MapErrNewService::new(self, f)
} }
/// Map this service's init error to a different error, returning a new service. /// Map this factory's init error to a different error, returning a new service.
fn map_init_err<F, E>(self, f: F) -> MapInitErr<Self, F, E, Config> fn map_init_err<F, E>(self, f: F) -> MapInitErr<Self, F, E>
where where
Self: Sized, Self: Sized,
F: Fn(Self::InitError) -> E, F: Fn(Self::InitError) -> E,
{ {
MapInitErr::new(self, f) MapInitErr::new(self, f)
} }
/// Map config to a different error, returning a new service.
fn map_config<F, C>(self, f: F) -> MapConfig<Self, F, C>
where
Self: Sized,
F: Fn(&C) -> MappedConfig<Self::Config>,
{
MapConfig::new(self, f)
}
/// Replace config with unit
fn unit_config<C>(self) -> UnitConfig<Self, C>
where
Self: NewService<Config = ()> + Sized,
{
UnitConfig::new(self)
}
} }
impl<'a, S> Service for &'a mut S impl<'a, S> Service for &'a mut S
@ -410,34 +388,36 @@ where
} }
} }
impl<S, C> NewService<C> for Rc<S> impl<S> NewService for Rc<S>
where where
S: NewService<C>, S: NewService,
{ {
type Request = S::Request; type Request = S::Request;
type Response = S::Response; type Response = S::Response;
type Error = S::Error; type Error = S::Error;
type Config = S::Config;
type Service = S::Service; type Service = S::Service;
type InitError = S::InitError; type InitError = S::InitError;
type Future = S::Future; 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) self.as_ref().new_service(cfg)
} }
} }
impl<S, C> NewService<C> for Arc<S> impl<S> NewService for Arc<S>
where where
S: NewService<C>, S: NewService,
{ {
type Request = S::Request; type Request = S::Request;
type Response = S::Response; type Response = S::Response;
type Error = S::Error; type Error = S::Error;
type Config = S::Config;
type Service = S::Service; type Service = S::Service;
type InitError = S::InitError; type InitError = S::InitError;
type Future = S::Future; 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) self.as_ref().new_service(cfg)
} }
} }
@ -452,9 +432,9 @@ where
} }
/// Trait for types that can be converted to a `NewService` /// Trait for types that can be converted to a `NewService`
pub trait IntoNewService<T, C = ()> pub trait IntoNewService<T>
where where
T: NewService<C>, T: NewService,
{ {
/// Convert to an `NewService` /// Convert to an `NewService`
fn into_new_service(self) -> T; fn into_new_service(self) -> T;
@ -469,27 +449,9 @@ where
} }
} }
impl<T, C> IntoNewService<T, C> for T impl<T> IntoNewService<T> for T
where where
T: NewService<C>, T: NewService,
{
fn into_new_service(self) -> T {
self
}
}
/// Trait for types that can be converted to a configurable `NewService`
pub trait IntoConfigurableNewService<T, C>
where
T: NewService<C>,
{
/// Convert to an `NewService`
fn into_new_service(self) -> T;
}
impl<T, C> IntoConfigurableNewService<T, C> for T
where
T: NewService<C>,
{ {
fn into_new_service(self) -> T { fn into_new_service(self) -> T {
self self

View File

@ -97,17 +97,17 @@ where
} }
/// `MapNewService` new service combinator /// `MapNewService` new service combinator
pub struct MapNewService<A, F, Res, Cfg> { pub struct MapNewService<A, F, Res> {
a: A, a: A,
f: F, f: F,
r: PhantomData<(Res, Cfg)>, r: PhantomData<Res>,
} }
impl<A, F, Res, Cfg> MapNewService<A, F, Res, Cfg> { impl<A, F, Res> MapNewService<A, F, Res> {
/// Create new `Map` new service instance /// Create new `Map` new service instance
pub fn new(a: A, f: F) -> Self pub fn new(a: A, f: F) -> Self
where where
A: NewService<Cfg>, A: NewService,
F: FnMut(A::Response) -> Res, F: FnMut(A::Response) -> Res,
{ {
Self { Self {
@ -118,7 +118,7 @@ impl<A, F, Res, Cfg> MapNewService<A, F, Res, Cfg> {
} }
} }
impl<A, F, Res, Cfg> Clone for MapNewService<A, F, Res, Cfg> impl<A, F, Res> Clone for MapNewService<A, F, Res>
where where
A: Clone, A: Clone,
F: Clone, F: Clone,
@ -132,36 +132,37 @@ where
} }
} }
impl<A, F, Res, Cfg> NewService<Cfg> for MapNewService<A, F, Res, Cfg> impl<A, F, Res> NewService for MapNewService<A, F, Res>
where where
A: NewService<Cfg>, A: NewService,
F: FnMut(A::Response) -> Res + Clone, F: FnMut(A::Response) -> Res + Clone,
{ {
type Request = A::Request; type Request = A::Request;
type Response = Res; type Response = Res;
type Error = A::Error; type Error = A::Error;
type Config = A::Config;
type Service = Map<A::Service, F, Res>; type Service = Map<A::Service, F, Res>;
type InitError = A::InitError; type InitError = A::InitError;
type Future = MapNewServiceFuture<A, F, Res, Cfg>; type Future = MapNewServiceFuture<A, F, Res>;
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()) MapNewServiceFuture::new(self.a.new_service(cfg), self.f.clone())
} }
} }
pub struct MapNewServiceFuture<A, F, Res, Cfg> pub struct MapNewServiceFuture<A, F, Res>
where where
A: NewService<Cfg>, A: NewService,
F: FnMut(A::Response) -> Res, F: FnMut(A::Response) -> Res,
{ {
fut: A::Future, fut: A::Future,
f: Option<F>, f: Option<F>,
} }
impl<A, F, Res, Cfg> MapNewServiceFuture<A, F, Res, Cfg> impl<A, F, Res> MapNewServiceFuture<A, F, Res>
where where
A: NewService<Cfg>, A: NewService,
F: FnMut(A::Response) -> Res, F: FnMut(A::Response) -> Res,
{ {
fn new(fut: A::Future, f: F) -> Self { fn new(fut: A::Future, f: F) -> Self {
@ -169,9 +170,9 @@ where
} }
} }
impl<A, F, Res, Cfg> Future for MapNewServiceFuture<A, F, Res, Cfg> impl<A, F, Res> Future for MapNewServiceFuture<A, F, Res>
where where
A: NewService<Cfg>, A: NewService,
F: FnMut(A::Response) -> Res, F: FnMut(A::Response) -> Res,
{ {
type Item = Map<A::Service, F, Res>; type Item = Map<A::Service, F, Res>;

View File

@ -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, F, C> {
a: A,
f: F,
e: PhantomData<C>,
}
impl<A, F, C> MapConfig<A, F, C> {
/// Create new `MapConfig` combinator
pub fn new(a: A, f: F) -> Self
where
A: NewService,
F: Fn(&C) -> MappedConfig<A::Config>,
{
Self {
a,
f,
e: PhantomData,
}
}
}
impl<A, F, C> Clone for MapConfig<A, F, C>
where
A: Clone,
F: Clone,
{
fn clone(&self) -> Self {
Self {
a: self.a.clone(),
f: self.f.clone(),
e: PhantomData,
}
}
}
impl<A, F, C> NewService for MapConfig<A, F, C>
where
A: NewService,
F: Fn(&C) -> MappedConfig<A::Config>,
{
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, C> {
a: A,
e: PhantomData<C>,
}
impl<A, C> UnitConfig<A, C> {
/// Create new `UnitConfig` combinator
pub fn new(a: A) -> Self
where
A: NewService<Config = ()>,
{
Self { a, e: PhantomData }
}
}
impl<A, C> Clone for UnitConfig<A, C>
where
A: Clone,
{
fn clone(&self) -> Self {
Self {
a: self.a.clone(),
e: PhantomData,
}
}
}
impl<A, C> NewService for UnitConfig<A, C>
where
A: NewService<Config = ()>,
{
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(&())
}
}

View File

@ -98,19 +98,19 @@ where
/// service's error. /// service's error.
/// ///
/// This is created by the `NewServiceExt::map_err` method. /// This is created by the `NewServiceExt::map_err` method.
pub struct MapErrNewService<A, F, E, C> pub struct MapErrNewService<A, F, E>
where where
A: NewService<C>, A: NewService,
F: Fn(A::Error) -> E + Clone, F: Fn(A::Error) -> E + Clone,
{ {
a: A, a: A,
f: F, f: F,
e: PhantomData<(E, C)>, e: PhantomData<E>,
} }
impl<A, F, E, C> MapErrNewService<A, F, E, C> impl<A, F, E> MapErrNewService<A, F, E>
where where
A: NewService<C>, A: NewService,
F: Fn(A::Error) -> E + Clone, F: Fn(A::Error) -> E + Clone,
{ {
/// Create new `MapErr` new service instance /// Create new `MapErr` new service instance
@ -123,9 +123,9 @@ where
} }
} }
impl<A, F, E, C> Clone for MapErrNewService<A, F, E, C> impl<A, F, E> Clone for MapErrNewService<A, F, E>
where where
A: NewService<C> + Clone, A: NewService + Clone,
F: Fn(A::Error) -> E + Clone, F: Fn(A::Error) -> E + Clone,
{ {
fn clone(&self) -> Self { fn clone(&self) -> Self {
@ -137,36 +137,37 @@ where
} }
} }
impl<A, F, E, C> NewService<C> for MapErrNewService<A, F, E, C> impl<A, F, E> NewService for MapErrNewService<A, F, E>
where where
A: NewService<C>, A: NewService,
F: Fn(A::Error) -> E + Clone, F: Fn(A::Error) -> E + Clone,
{ {
type Request = A::Request; type Request = A::Request;
type Response = A::Response; type Response = A::Response;
type Error = E; type Error = E;
type Config = A::Config;
type Service = MapErr<A::Service, F, E>; type Service = MapErr<A::Service, F, E>;
type InitError = A::InitError; type InitError = A::InitError;
type Future = MapErrNewServiceFuture<A, F, E, C>; type Future = MapErrNewServiceFuture<A, F, E>;
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()) MapErrNewServiceFuture::new(self.a.new_service(cfg), self.f.clone())
} }
} }
pub struct MapErrNewServiceFuture<A, F, E, C> pub struct MapErrNewServiceFuture<A, F, E>
where where
A: NewService<C>, A: NewService,
F: Fn(A::Error) -> E, F: Fn(A::Error) -> E,
{ {
fut: A::Future, fut: A::Future,
f: F, f: F,
} }
impl<A, F, E, C> MapErrNewServiceFuture<A, F, E, C> impl<A, F, E> MapErrNewServiceFuture<A, F, E>
where where
A: NewService<C>, A: NewService,
F: Fn(A::Error) -> E, F: Fn(A::Error) -> E,
{ {
fn new(fut: A::Future, f: F) -> Self { fn new(fut: A::Future, f: F) -> Self {
@ -174,9 +175,9 @@ where
} }
} }
impl<A, F, E, C> Future for MapErrNewServiceFuture<A, F, E, C> impl<A, F, E> Future for MapErrNewServiceFuture<A, F, E>
where where
A: NewService<C>, A: NewService,
F: Fn(A::Error) -> E + Clone, F: Fn(A::Error) -> E + Clone,
{ {
type Item = MapErr<A::Service, F, E>; type Item = MapErr<A::Service, F, E>;

View File

@ -5,17 +5,17 @@ use futures::{Future, Poll};
use super::NewService; use super::NewService;
/// `MapInitErr` service combinator /// `MapInitErr` service combinator
pub struct MapInitErr<A, F, E, C> { pub struct MapInitErr<A, F, E> {
a: A, a: A,
f: F, f: F,
e: PhantomData<(E, C)>, e: PhantomData<E>,
} }
impl<A, F, E, C> MapInitErr<A, F, E, C> { impl<A, F, E> MapInitErr<A, F, E> {
/// Create new `MapInitErr` combinator /// Create new `MapInitErr` combinator
pub fn new(a: A, f: F) -> Self pub fn new(a: A, f: F) -> Self
where where
A: NewService<C>, A: NewService,
F: Fn(A::InitError) -> E, F: Fn(A::InitError) -> E,
{ {
Self { Self {
@ -26,7 +26,7 @@ impl<A, F, E, C> MapInitErr<A, F, E, C> {
} }
} }
impl<A, F, E, C> Clone for MapInitErr<A, F, E, C> impl<A, F, E> Clone for MapInitErr<A, F, E>
where where
A: Clone, A: Clone,
F: Clone, F: Clone,
@ -40,36 +40,37 @@ where
} }
} }
impl<A, F, E, C> NewService<C> for MapInitErr<A, F, E, C> impl<A, F, E> NewService for MapInitErr<A, F, E>
where where
A: NewService<C>, A: NewService,
F: Fn(A::InitError) -> E + Clone, F: Fn(A::InitError) -> E + Clone,
{ {
type Request = A::Request; type Request = A::Request;
type Response = A::Response; type Response = A::Response;
type Error = A::Error; type Error = A::Error;
type Config = A::Config;
type Service = A::Service; type Service = A::Service;
type InitError = E; type InitError = E;
type Future = MapInitErrFuture<A, F, E, C>; type Future = MapInitErrFuture<A, F, E>;
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()) MapInitErrFuture::new(self.a.new_service(cfg), self.f.clone())
} }
} }
pub struct MapInitErrFuture<A, F, E, C> pub struct MapInitErrFuture<A, F, E>
where where
A: NewService<C>, A: NewService,
F: Fn(A::InitError) -> E, F: Fn(A::InitError) -> E,
{ {
f: F, f: F,
fut: A::Future, fut: A::Future,
} }
impl<A, F, E, C> MapInitErrFuture<A, F, E, C> impl<A, F, E> MapInitErrFuture<A, F, E>
where where
A: NewService<C>, A: NewService,
F: Fn(A::InitError) -> E, F: Fn(A::InitError) -> E,
{ {
fn new(fut: A::Future, f: F) -> Self { fn new(fut: A::Future, f: F) -> Self {
@ -77,9 +78,9 @@ where
} }
} }
impl<A, F, E, C> Future for MapInitErrFuture<A, F, E, C> impl<A, F, E> Future for MapInitErrFuture<A, F, E>
where where
A: NewService<C>, A: NewService,
F: Fn(A::InitError) -> E, F: Fn(A::InitError) -> E,
{ {
type Item = A::Service; type Item = A::Service;

View File

@ -1,5 +1,3 @@
use std::marker::PhantomData;
use futures::{Async, Future, Poll}; use futures::{Async, Future, Poll};
use super::{IntoNewService, NewService, Service}; use super::{IntoNewService, NewService, Service};
@ -115,38 +113,36 @@ where
} }
/// `ThenNewService` new service combinator /// `ThenNewService` new service combinator
pub struct ThenNewService<A, B, C> { pub struct ThenNewService<A, B> {
a: A, a: A,
b: B, b: B,
_t: PhantomData<C>,
} }
impl<A, B, C> ThenNewService<A, B, C> { impl<A, B> ThenNewService<A, B> {
/// Create new `AndThen` combinator /// Create new `AndThen` combinator
pub fn new<F>(a: A, f: F) -> Self pub fn new<F>(a: A, f: F) -> Self
where where
A: NewService<C>, A: NewService,
B: NewService< B: NewService<
C, Config = A::Config,
Request = Result<A::Response, A::Error>, Request = Result<A::Response, A::Error>,
Error = A::Error, Error = A::Error,
InitError = A::InitError, InitError = A::InitError,
>, >,
F: IntoNewService<B, C>, F: IntoNewService<B>,
{ {
Self { Self {
a, a,
b: f.into_new_service(), b: f.into_new_service(),
_t: PhantomData,
} }
} }
} }
impl<A, B, C> NewService<C> for ThenNewService<A, B, C> impl<A, B> NewService for ThenNewService<A, B>
where where
A: NewService<C>, A: NewService,
B: NewService< B: NewService<
C, Config = A::Config,
Request = Result<A::Response, A::Error>, Request = Result<A::Response, A::Error>,
Error = A::Error, Error = A::Error,
InitError = A::InitError, InitError = A::InitError,
@ -155,17 +151,18 @@ where
type Request = A::Request; type Request = A::Request;
type Response = B::Response; type Response = B::Response;
type Error = A::Error; type Error = A::Error;
type Config = A::Config;
type Service = Then<A::Service, B::Service>; type Service = Then<A::Service, B::Service>;
type InitError = A::InitError; type InitError = A::InitError;
type Future = ThenNewServiceFuture<A, B, C>; type Future = ThenNewServiceFuture<A, B>;
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)) ThenNewServiceFuture::new(self.a.new_service(cfg), self.b.new_service(cfg))
} }
} }
impl<A, B, C> Clone for ThenNewService<A, B, C> impl<A, B> Clone for ThenNewService<A, B>
where where
A: Clone, A: Clone,
B: Clone, B: Clone,
@ -174,16 +171,15 @@ where
Self { Self {
a: self.a.clone(), a: self.a.clone(),
b: self.b.clone(), b: self.b.clone(),
_t: PhantomData,
} }
} }
} }
pub struct ThenNewServiceFuture<A, B, C> pub struct ThenNewServiceFuture<A, B>
where where
A: NewService<C>, A: NewService,
B: NewService< B: NewService<
C, Config = A::Config,
Request = Result<A::Response, A::Error>, Request = Result<A::Response, A::Error>,
Error = A::Error, Error = A::Error,
InitError = A::InitError, InitError = A::InitError,
@ -195,11 +191,11 @@ where
b: Option<B::Service>, b: Option<B::Service>,
} }
impl<A, B, C> ThenNewServiceFuture<A, B, C> impl<A, B> ThenNewServiceFuture<A, B>
where where
A: NewService<C>, A: NewService,
B: NewService< B: NewService<
C, Config = A::Config,
Request = Result<A::Response, A::Error>, Request = Result<A::Response, A::Error>,
Error = A::Error, Error = A::Error,
InitError = A::InitError, InitError = A::InitError,
@ -215,11 +211,11 @@ where
} }
} }
impl<A, B, C> Future for ThenNewServiceFuture<A, B, C> impl<A, B> Future for ThenNewServiceFuture<A, B>
where where
A: NewService<C>, A: NewService,
B: NewService< B: NewService<
C, Config = A::Config,
Request = Result<A::Response, A::Error>, Request = Result<A::Response, A::Error>,
Error = A::Error, Error = A::Error,
InitError = A::InitError, InitError = A::InitError,

View File

@ -133,11 +133,11 @@ where
/// Apply transform to service factory. Function returns /// Apply transform to service factory. Function returns
/// services factory that in initialization creates /// services factory that in initialization creates
/// service and applies transform to this service. /// service and applies transform to this service.
pub fn apply_transform<T, S, C, F, U>( pub fn apply_transform<T, S, F, U>(
t: F, t: F,
service: U, service: U,
) -> impl NewService< ) -> impl NewService<
C, Config = S::Config,
Request = T::Request, Request = T::Request,
Response = T::Response, Response = T::Response,
Error = T::Error, Error = T::Error,
@ -145,24 +145,23 @@ pub fn apply_transform<T, S, C, F, U>(
InitError = S::InitError, InitError = S::InitError,
> + Clone > + Clone
where where
S: NewService<C>, S: NewService,
T: Transform<S::Service, InitError = S::InitError>, T: Transform<S::Service, InitError = S::InitError>,
F: IntoTransform<T, S::Service>, F: IntoTransform<T, S::Service>,
U: IntoNewService<S, C>, U: IntoNewService<S>,
{ {
ApplyTransform::new(t.into_transform(), service.into_new_service()) ApplyTransform::new(t.into_transform(), service.into_new_service())
} }
/// `Apply` transform to new service /// `Apply` transform to new service
pub struct ApplyTransform<T, S, C> { pub struct ApplyTransform<T, S> {
s: Rc<S>, s: Rc<S>,
t: Rc<T>, t: Rc<T>,
_t: std::marker::PhantomData<C>,
} }
impl<T, S, C> ApplyTransform<T, S, C> impl<T, S> ApplyTransform<T, S>
where where
S: NewService<C>, S: NewService,
T: Transform<S::Service, InitError = S::InitError>, T: Transform<S::Service, InitError = S::InitError>,
{ {
/// Create new `ApplyTransform` new service instance /// Create new `ApplyTransform` new service instance
@ -170,35 +169,34 @@ where
Self { Self {
s: Rc::new(service), s: Rc::new(service),
t: Rc::new(t.into_transform()), t: Rc::new(t.into_transform()),
_t: std::marker::PhantomData,
} }
} }
} }
impl<T, S, C> Clone for ApplyTransform<T, S, C> { impl<T, S> Clone for ApplyTransform<T, S> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
ApplyTransform { ApplyTransform {
s: self.s.clone(), s: self.s.clone(),
t: self.t.clone(), t: self.t.clone(),
_t: std::marker::PhantomData,
} }
} }
} }
impl<T, S, C> NewService<C> for ApplyTransform<T, S, C> impl<T, S> NewService for ApplyTransform<T, S>
where where
S: NewService<C>, S: NewService,
T: Transform<S::Service, InitError = S::InitError>, T: Transform<S::Service, InitError = S::InitError>,
{ {
type Request = T::Request; type Request = T::Request;
type Response = T::Response; type Response = T::Response;
type Error = T::Error; type Error = T::Error;
type Config = S::Config;
type Service = T::Transform; type Service = T::Transform;
type InitError = T::InitError; type InitError = T::InitError;
type Future = ApplyTransformFuture<T, S, C>; type Future = ApplyTransformFuture<T, S>;
fn new_service(&self, cfg: &C) -> Self::Future { fn new_service(&self, cfg: &S::Config) -> Self::Future {
ApplyTransformFuture { ApplyTransformFuture {
t_cell: self.t.clone(), t_cell: self.t.clone(),
fut_a: self.s.new_service(cfg).into_future(), fut_a: self.s.new_service(cfg).into_future(),
@ -207,9 +205,9 @@ where
} }
} }
pub struct ApplyTransformFuture<T, S, C> pub struct ApplyTransformFuture<T, S>
where where
S: NewService<C>, S: NewService,
T: Transform<S::Service, InitError = S::InitError>, T: Transform<S::Service, InitError = S::InitError>,
{ {
fut_a: S::Future, fut_a: S::Future,
@ -217,9 +215,9 @@ where
t_cell: Rc<T>, t_cell: Rc<T>,
} }
impl<T, S, C> Future for ApplyTransformFuture<T, S, C> impl<T, S> Future for ApplyTransformFuture<T, S>
where where
S: NewService<C>, S: NewService,
T: Transform<S::Service, InitError = S::InitError>, T: Transform<S::Service, InitError = S::InitError>,
{ {
type Item = T::Transform; type Item = T::Transform;

View File

@ -19,11 +19,11 @@ use tokio_tcp::TcpStream;
/// # Examples /// # Examples
/// ///
/// ```rust /// ```rust
/// use actix_service::{fn_service, IntoNewService}; /// use actix_service::{service_fn, IntoNewService};
/// use actix_test_server::TestServer; /// use actix_test_server::TestServer;
/// ///
/// fn main() { /// fn main() {
/// let srv = TestServer::with(|| fn_service( /// let srv = TestServer::with(|| service_fn(
/// |sock| { /// |sock| {
/// println!("New connection: {:?}", sock); /// println!("New connection: {:?}", sock);
/// Ok::<_, ()>(()) /// Ok::<_, ()>(())

View File

@ -1,5 +1,18 @@
# Changes # 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 ## [0.3.5] - 2019-04-04

View File

@ -21,7 +21,8 @@ path = "src/lib.rs"
actix-service = "0.3.3" actix-service = "0.3.3"
actix-codec = "0.1.1" actix-codec = "0.1.1"
bytes = "0.4" bytes = "0.4"
futures = "0.1.24" either = "1.5.2"
futures = "0.1.25"
tokio-timer = "0.2.8" tokio-timer = "0.2.8"
tokio-current-thread = "0.1.4" tokio-current-thread = "0.1.4"
log = "0.4" log = "0.4"

View File

@ -1,5 +1,5 @@
//! Contains `Either` service and related types and functions. //! 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}; use futures::{future, try_ready, Async, Future, IntoFuture, Poll};
/// Combine two different service types into a single type. /// 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. /// Both services must be of the same request, response, and error types.
/// `EitherService` is useful for handling conditional branching in service /// `EitherService` is useful for handling conditional branching in service
/// middleware to different inner service types. /// middleware to different inner service types.
pub enum EitherService<A, B> { pub struct EitherService<A, B> {
A(A), left: A,
B(B), right: B,
} }
impl<A: Clone, B: Clone> Clone for EitherService<A, B> { impl<A: Clone, B: Clone> Clone for EitherService<A, B> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
match self { EitherService {
EitherService::A(srv) => EitherService::A(srv.clone()), left: self.left.clone(),
EitherService::B(srv) => EitherService::B(srv.clone()), right: self.right.clone(),
} }
} }
} }
@ -24,129 +24,130 @@ impl<A: Clone, B: Clone> Clone for EitherService<A, B> {
impl<A, B> Service for EitherService<A, B> impl<A, B> Service for EitherService<A, B>
where where
A: Service, A: Service,
B: Service<Request = A::Request, Response = A::Response, Error = A::Error>, B: Service<Response = A::Response, Error = A::Error>,
{ {
type Request = A::Request; type Request = either::Either<A::Request, B::Request>;
type Response = A::Response; type Response = A::Response;
type Error = A::Error; type Error = A::Error;
type Future = future::Either<A::Future, B::Future>; type Future = future::Either<A::Future, B::Future>;
fn poll_ready(&mut self) -> Poll<(), Self::Error> { fn poll_ready(&mut self) -> Poll<(), Self::Error> {
match self { let left = self.left.poll_ready()?;
EitherService::A(ref mut inner) => inner.poll_ready(), let right = self.right.poll_ready()?;
EitherService::B(ref mut inner) => inner.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 { fn call(&mut self, req: either::Either<A::Request, B::Request>) -> Self::Future {
match self { match req {
EitherService::A(ref mut inner) => future::Either::A(inner.call(req)), either::Either::Left(req) => future::Either::A(self.left.call(req)),
EitherService::B(ref mut inner) => future::Either::B(inner.call(req)), either::Either::Right(req) => future::Either::B(self.right.call(req)),
} }
} }
} }
/// Combine two different new service types into a single type. /// Combine two different new service types into a single service.
pub enum Either<A, B> { pub struct Either<A, B> {
A(A), left: A,
B(B), right: B,
} }
impl<A, B> Either<A, B> { impl<A, B> Either<A, B> {
pub fn new_a<C>(srv: A) -> Self pub fn new_a<F>(srv: F) -> Either<A, ()>
where where
A: NewService<C>, A: NewService,
B: NewService< F: IntoNewService<A>,
C,
Request = A::Request,
Response = A::Response,
Error = A::Error,
InitError = A::InitError,
>,
{ {
Either::A(srv) Either {
left: srv.into_new_service(),
right: (),
}
} }
pub fn new_b<C>(srv: B) -> Self pub fn new_b<F>(srv: F) -> Either<(), B>
where where
A: NewService<C>, B: NewService,
B: NewService< F: IntoNewService<B>,
C,
Request = A::Request,
Response = A::Response,
Error = A::Error,
InitError = A::InitError,
>,
{ {
Either::B(srv) Either {
left: (),
right: srv.into_new_service(),
}
} }
} }
impl<A, B, C> NewService<C> for Either<A, B> impl<A, B> NewService for Either<A, B>
where where
A: NewService<C>, A: NewService,
B: NewService< B: NewService<
C, Config = A::Config,
Request = A::Request,
Response = A::Response, Response = A::Response,
Error = A::Error, Error = A::Error,
InitError = A::InitError, InitError = A::InitError,
>, >,
{ {
type Request = A::Request; type Request = either::Either<A::Request, B::Request>;
type Response = A::Response; type Response = A::Response;
type Error = A::Error; type Error = A::Error;
type InitError = A::InitError; type InitError = A::InitError;
type Config = A::Config;
type Service = EitherService<A::Service, B::Service>; type Service = EitherService<A::Service, B::Service>;
type Future = EitherNewService<A, B, C>; type Future = EitherNewService<A, B>;
fn new_service(&self, cfg: &C) -> Self::Future { fn new_service(&self, cfg: &A::Config) -> Self::Future {
match self { EitherNewService {
Either::A(ref inner) => EitherNewService::A(inner.new_service(cfg)), left: None,
Either::B(ref inner) => EitherNewService::B(inner.new_service(cfg)), right: None,
left_fut: self.left.new_service(cfg),
right_fut: self.right.new_service(cfg),
} }
} }
} }
impl<A: Clone, B: Clone> Clone for Either<A, B> { impl<A: Clone, B: Clone> Clone for Either<A, B> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
match self { Self {
Either::A(srv) => Either::A(srv.clone()), left: self.left.clone(),
Either::B(srv) => Either::B(srv.clone()), right: self.right.clone(),
} }
} }
} }
#[doc(hidden)] #[doc(hidden)]
pub enum EitherNewService<A: NewService<C>, B: NewService<C>, C> { pub struct EitherNewService<A: NewService, B: NewService> {
A(<A::Future as IntoFuture>::Future), left: Option<A::Service>,
B(<B::Future as IntoFuture>::Future), right: Option<B::Service>,
left_fut: <A::Future as IntoFuture>::Future,
right_fut: <B::Future as IntoFuture>::Future,
} }
impl<A, B, C> Future for EitherNewService<A, B, C> impl<A, B> Future for EitherNewService<A, B>
where where
A: NewService<C>, A: NewService,
B: NewService< B: NewService<Response = A::Response, Error = A::Error, InitError = A::InitError>,
C,
Request = A::Request,
Response = A::Response,
Error = A::Error,
InitError = A::InitError,
>,
{ {
type Item = EitherService<A::Service, B::Service>; type Item = EitherService<A::Service, B::Service>;
type Error = A::InitError; type Error = A::InitError;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> { fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
match self { if self.left.is_none() {
EitherNewService::A(ref mut fut) => { self.left = Some(try_ready!(self.left_fut.poll()));
let service = try_ready!(fut.poll()); }
Ok(Async::Ready(EitherService::A(service))) if self.right.is_none() {
} self.right = Some(try_ready!(self.right_fut.poll()));
EitherNewService::B(ref mut fut) => { }
let service = try_ready!(fut.poll());
Ok(Async::Ready(EitherService::B(service))) 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)
} }
} }
} }

View File

@ -1,14 +1,12 @@
//! Framed dispatcher service and related utilities //! Framed dispatcher service and related utilities
use std::collections::VecDeque; use std::collections::VecDeque;
use std::marker::PhantomData; use std::{fmt, mem};
use std::mem;
use actix_codec::{AsyncRead, AsyncWrite, Decoder, Encoder, Framed}; use actix_codec::{AsyncRead, AsyncWrite, Decoder, Encoder, Framed};
use actix_service::{IntoNewService, IntoService, NewService, Service}; use actix_service::{IntoService, Service};
use futures::future::{ok, FutureResult};
use futures::task::AtomicTask; use futures::task::AtomicTask;
use futures::unsync::mpsc; use futures::unsync::mpsc;
use futures::{Async, Future, IntoFuture, Poll, Sink, Stream}; use futures::{Async, Future, Poll, Sink, Stream};
use log::debug; use log::debug;
use crate::cell::Cell; use crate::cell::Cell;
@ -16,156 +14,6 @@ use crate::cell::Cell;
type Request<U> = <U as Decoder>::Item; type Request<U> = <U as Decoder>::Item;
type Response<U> = <U as Encoder>::Item; type Response<U> = <U as Encoder>::Item;
pub struct FramedNewService<S, T, U, C> {
factory: S,
_t: PhantomData<(T, U, C)>,
}
impl<S, T, U, C> FramedNewService<S, T, U, C>
where
C: Clone,
S: NewService<C, Request = Request<U>, Response = Response<U>>,
S::Error: 'static,
<S::Service as Service>::Future: 'static,
T: AsyncRead + AsyncWrite,
U: Decoder + Encoder,
<U as Encoder>::Item: 'static,
<U as Encoder>::Error: std::fmt::Debug,
{
pub fn new<F1: IntoNewService<S, C>>(factory: F1) -> Self {
Self {
factory: factory.into_new_service(),
_t: PhantomData,
}
}
}
impl<S, T, U, C> Clone for FramedNewService<S, T, U, C>
where
S: Clone,
{
fn clone(&self) -> Self {
Self {
factory: self.factory.clone(),
_t: PhantomData,
}
}
}
impl<S, T, U, C> NewService<C> for FramedNewService<S, T, U, C>
where
C: Clone,
S: NewService<C, Request = Request<U>, Response = Response<U>> + Clone,
S::Error: 'static,
<S::Service as Service>::Future: 'static,
T: AsyncRead + AsyncWrite,
U: Decoder + Encoder,
<U as Encoder>::Item: 'static,
<U as Encoder>::Error: std::fmt::Debug,
{
type Request = Framed<T, U>;
type Response = FramedTransport<S::Service, T, U>;
type Error = S::InitError;
type InitError = S::InitError;
type Service = FramedService<S, T, U, C>;
type Future = FutureResult<Self::Service, Self::InitError>;
fn new_service(&self, cfg: &C) -> Self::Future {
ok(FramedService {
factory: self.factory.clone(),
config: cfg.clone(),
_t: PhantomData,
})
}
}
pub struct FramedService<S, T, U, C> {
factory: S,
config: C,
_t: PhantomData<(T, U)>,
}
impl<S, T, U, C> Clone for FramedService<S, T, U, C>
where
S: Clone,
C: Clone,
{
fn clone(&self) -> Self {
Self {
factory: self.factory.clone(),
config: self.config.clone(),
_t: PhantomData,
}
}
}
impl<S, T, U, C> Service for FramedService<S, T, U, C>
where
S: NewService<C, Request = Request<U>, Response = Response<U>>,
S::Error: 'static,
<S::Service as Service>::Future: 'static,
T: AsyncRead + AsyncWrite,
U: Decoder + Encoder,
<U as Encoder>::Item: 'static,
<U as Encoder>::Error: std::fmt::Debug,
C: Clone,
{
type Request = Framed<T, U>;
type Response = FramedTransport<S::Service, T, U>;
type Error = S::InitError;
type Future = FramedServiceResponseFuture<S, T, U, C>;
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
Ok(Async::Ready(()))
}
fn call(&mut self, req: Framed<T, U>) -> Self::Future {
FramedServiceResponseFuture {
fut: self.factory.new_service(&self.config),
framed: Some(req),
}
}
}
#[doc(hidden)]
pub struct FramedServiceResponseFuture<S, T, U, C>
where
S: NewService<C, Request = Request<U>, Response = Response<U>>,
S::Error: 'static,
<S::Service as Service>::Future: 'static,
T: AsyncRead + AsyncWrite,
U: Decoder + Encoder,
<U as Encoder>::Item: 'static,
<U as Encoder>::Error: std::fmt::Debug,
{
fut: <S::Future as IntoFuture>::Future,
framed: Option<Framed<T, U>>,
}
impl<S, T, U, C> Future for FramedServiceResponseFuture<S, T, U, C>
where
S: NewService<C, Request = Request<U>, Response = Response<U>>,
S::Error: 'static,
<S::Service as Service>::Future: 'static,
T: AsyncRead + AsyncWrite,
U: Decoder + Encoder,
<U as Encoder>::Item: 'static,
<U as Encoder>::Error: std::fmt::Debug,
{
type Item = FramedTransport<S::Service, T, U>;
type Error = S::InitError;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
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 /// Framed transport errors
pub enum FramedTransportError<E, U: Encoder + Decoder> { pub enum FramedTransportError<E, U: Encoder + Decoder> {
Service(E), Service(E),
@ -179,6 +27,42 @@ impl<E, U: Encoder + Decoder> From<E> for FramedTransportError<E, U> {
} }
} }
impl<E, U: Encoder + Decoder> fmt::Debug for FramedTransportError<E, U>
where
E: fmt::Debug,
<U as Encoder>::Error: fmt::Debug,
<U as Decoder>::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<E, U: Encoder + Decoder> fmt::Display for FramedTransportError<E, U>
where
E: fmt::Display,
<U as Encoder>::Error: fmt::Debug,
<U as Decoder>::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<T> { pub enum FramedMessage<T> {
Message(T), Message(T),
Close, Close,
@ -444,78 +328,3 @@ where
} }
} }
} }
pub struct IntoFramed<T, U, F>
where
T: AsyncRead + AsyncWrite,
F: Fn() -> U + Send + Clone + 'static,
U: Encoder + Decoder,
{
factory: F,
_t: PhantomData<(T,)>,
}
impl<T, U, F> IntoFramed<T, U, F>
where
T: AsyncRead + AsyncWrite,
F: Fn() -> U + Send + Clone + 'static,
U: Encoder + Decoder,
{
pub fn new(factory: F) -> Self {
IntoFramed {
factory,
_t: PhantomData,
}
}
}
impl<T, C, U, F> NewService<C> for IntoFramed<T, U, F>
where
T: AsyncRead + AsyncWrite,
F: Fn() -> U + Send + Clone + 'static,
U: Encoder + Decoder,
{
type Request = T;
type Response = Framed<T, U>;
type Error = ();
type InitError = ();
type Service = IntoFramedService<T, U, F>;
type Future = FutureResult<Self::Service, Self::InitError>;
fn new_service(&self, _: &C) -> Self::Future {
ok(IntoFramedService {
factory: self.factory.clone(),
_t: PhantomData,
})
}
}
pub struct IntoFramedService<T, U, F>
where
T: AsyncRead + AsyncWrite,
F: Fn() -> U + Send + Clone + 'static,
U: Encoder + Decoder,
{
factory: F,
_t: PhantomData<(T,)>,
}
impl<T, U, F> Service for IntoFramedService<T, U, F>
where
T: AsyncRead + AsyncWrite,
F: Fn() -> U + Send + Clone + 'static,
U: Encoder + Decoder,
{
type Request = T;
type Response = Framed<T, U>;
type Error = ();
type Future = FutureResult<Self::Response, Self::Error>;
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)()))
}
}

View File

@ -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::future::{ok, FutureResult};
use futures::{Async, Future, Poll}; use futures::{Async, Future, Poll};
@ -28,7 +30,7 @@ impl<S: Service> Transform<S> for InFlight {
type Request = S::Request; type Request = S::Request;
type Response = S::Response; type Response = S::Response;
type Error = S::Error; type Error = S::Error;
type InitError = Void; type InitError = Infallible;
type Transform = InFlightService<S>; type Transform = InFlightService<S>;
type Future = FutureResult<Self::Transform, Self::InitError>; type Future = FutureResult<Self::Transform, Self::InitError>;

View File

@ -1,7 +1,8 @@
use std::convert::Infallible;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use actix_service::{NewService, Service, Void}; use actix_service::{NewService, Service};
use futures::future::{ok, FutureResult}; use futures::future::{ok, FutureResult};
use futures::{Async, Future, Poll}; use futures::{Async, Future, Poll};
use tokio_timer::Delay; use tokio_timer::Delay;
@ -43,14 +44,15 @@ where
} }
} }
impl<R, E, F> NewService<()> for KeepAlive<R, E, F> impl<R, E, F> NewService for KeepAlive<R, E, F>
where where
F: Fn() -> E + Clone, F: Fn() -> E + Clone,
{ {
type Request = R; type Request = R;
type Response = R; type Response = R;
type Error = E; type Error = E;
type InitError = Void; type InitError = Infallible;
type Config = ();
type Service = KeepAliveService<R, E, F>; type Service = KeepAliveService<R, E, F>;
type Future = FutureResult<Self::Service, Self::InitError>; type Future = FutureResult<Self::Service, Self::InitError>;

View File

@ -1,9 +1,10 @@
use std::collections::VecDeque; use std::collections::VecDeque;
use std::convert::Infallible;
use std::fmt; use std::fmt;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::rc::Rc; use std::rc::Rc;
use actix_service::{IntoService, Service, Transform, Void}; use actix_service::{IntoService, Service, Transform};
use futures::future::{ok, FutureResult}; use futures::future::{ok, FutureResult};
use futures::task::AtomicTask; use futures::task::AtomicTask;
use futures::unsync::oneshot; use futures::unsync::oneshot;
@ -90,7 +91,7 @@ where
type Request = S::Request; type Request = S::Request;
type Response = S::Response; type Response = S::Response;
type Error = InOrderError<S::Error>; type Error = InOrderError<S::Error>;
type InitError = Void; type InitError = Infallible;
type Transform = InOrderService<S>; type Transform = InOrderService<S>;
type Future = FutureResult<Self::Transform, Self::InitError>; type Future = FutureResult<Self::Transform, Self::InitError>;

View File

@ -1,10 +1,9 @@
use std::marker::PhantomData; use std::marker::PhantomData;
use std::rc::Rc; use std::rc::Rc;
use actix_service::{IntoNewService, IntoService, NewService, Service}; use actix_service::{IntoService, NewService, Service};
use futures::future::{ok, Future, FutureResult};
use futures::unsync::mpsc; use futures::unsync::mpsc;
use futures::{Async, Poll, Stream}; use futures::{Async, Future, Poll, Stream};
type Request<T> = Result<<T as IntoStream>::Item, <T as IntoStream>::Error>; type Request<T> = Result<<T as IntoStream>::Item, <T as IntoStream>::Error>;
@ -29,76 +28,19 @@ where
} }
} }
pub struct StreamNewService<S, T, E, C> { pub struct StreamService<S, T: NewService, E> {
factory: Rc<T>, factory: Rc<T>,
_t: PhantomData<(S, E, C)>, config: T::Config,
}
impl<S, T, E, C> StreamNewService<S, T, E, C>
where
C: Clone,
S: IntoStream,
T: NewService<C, Request = Request<S>, Response = (), Error = E, InitError = E>,
T::Future: 'static,
T::Service: 'static,
<T::Service as Service>::Future: 'static,
{
pub fn new<F: IntoNewService<T, C>>(factory: F) -> Self {
Self {
factory: Rc::new(factory.into_new_service()),
_t: PhantomData,
}
}
}
impl<S, T, E, C> Clone for StreamNewService<S, T, E, C> {
fn clone(&self) -> Self {
Self {
factory: self.factory.clone(),
_t: PhantomData,
}
}
}
impl<S, T, E, C> NewService<C> for StreamNewService<S, T, E, C>
where
C: Clone,
S: IntoStream + 'static,
T: NewService<C, Request = Request<S>, Response = (), Error = E, InitError = E>,
T::Future: 'static,
T::Service: 'static,
<T::Service as Service>::Future: 'static,
{
type Request = S;
type Response = ();
type Error = E;
type InitError = E;
type Service = StreamService<S, T, E, C>;
type Future = FutureResult<Self::Service, E>;
fn new_service(&self, cfg: &C) -> Self::Future {
ok(StreamService {
factory: self.factory.clone(),
config: cfg.clone(),
_t: PhantomData,
})
}
}
pub struct StreamService<S, T, E, C = ()> {
factory: Rc<T>,
config: C,
_t: PhantomData<(S, E)>, _t: PhantomData<(S, E)>,
} }
impl<S, T, E, C> Service for StreamService<S, T, E, C> impl<S, T, E> Service for StreamService<S, T, E>
where where
S: IntoStream + 'static, S: IntoStream + 'static,
T: NewService<C, Request = Request<S>, Response = (), Error = E, InitError = E>, T: NewService<Request = Request<S>, Response = (), Error = E, InitError = E>,
T::Future: 'static, T::Future: 'static,
T::Service: 'static, T::Service: 'static,
<T::Service as Service>::Future: 'static, <T::Service as Service>::Future: 'static,
C: Clone,
{ {
type Request = S; type Request = S;
type Response = (); type Response = ();
@ -207,83 +149,3 @@ impl<F: Future> Future for StreamDispatcherService<F> {
} }
} }
} }
/// `NewService` that implements, read one item from the stream.
pub struct TakeItem<T> {
_t: PhantomData<T>,
}
impl<T> TakeItem<T> {
/// Create new `TakeRequest` instance.
pub fn new() -> Self {
TakeItem { _t: PhantomData }
}
}
impl<T> Default for TakeItem<T> {
fn default() -> Self {
TakeItem { _t: PhantomData }
}
}
impl<T> Clone for TakeItem<T> {
fn clone(&self) -> TakeItem<T> {
TakeItem { _t: PhantomData }
}
}
impl<T: Stream, C> NewService<C> for TakeItem<T> {
type Request = T;
type Response = (Option<T::Item>, T);
type Error = T::Error;
type InitError = ();
type Service = TakeItemService<T>;
type Future = FutureResult<Self::Service, Self::InitError>;
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> {
_t: PhantomData<T>,
}
impl<T> Clone for TakeItemService<T> {
fn clone(&self) -> TakeItemService<T> {
TakeItemService { _t: PhantomData }
}
}
impl<T: Stream> Service for TakeItemService<T> {
type Request = T;
type Response = (Option<T::Item>, T);
type Error = T::Error;
type Future = TakeItemServiceResponse<T>;
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<T: Stream> {
stream: Option<T>,
}
impl<T: Stream> Future for TakeItemServiceResponse<T> {
type Item = (Option<T::Item>, T);
type Error = T::Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
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),
}
}
}

View File

@ -1,6 +1,7 @@
use std::convert::Infallible;
use std::time::{self, Duration, Instant}; use std::time::{self, Duration, Instant};
use actix_service::{NewService, Service, Void}; use actix_service::{NewService, Service};
use futures::future::{ok, FutureResult}; use futures::future::{ok, FutureResult};
use futures::{Async, Future, Poll}; use futures::{Async, Future, Poll};
use tokio_timer::sleep; use tokio_timer::sleep;
@ -41,11 +42,12 @@ impl Default for LowResTime {
} }
} }
impl NewService<()> for LowResTime { impl NewService for LowResTime {
type Request = (); type Request = ();
type Response = Instant; type Response = Instant;
type Error = Void; type Error = Infallible;
type InitError = Void; type InitError = Infallible;
type Config = ();
type Service = LowResTimeService; type Service = LowResTimeService;
type Future = FutureResult<Self::Service, Self::InitError>; type Future = FutureResult<Self::Service, Self::InitError>;
@ -91,7 +93,7 @@ impl LowResTimeService {
impl Service for LowResTimeService { impl Service for LowResTimeService {
type Request = (); type Request = ();
type Response = Instant; type Response = Instant;
type Error = Void; type Error = Infallible;
type Future = FutureResult<Self::Response, Self::Error>; type Future = FutureResult<Self::Response, Self::Error>;
fn poll_ready(&mut self) -> Poll<(), Self::Error> { fn poll_ready(&mut self) -> Poll<(), Self::Error> {

View File

@ -10,7 +10,7 @@ use std::{env, fmt, io};
use actix_codec::{AsyncRead, AsyncWrite}; use actix_codec::{AsyncRead, AsyncWrite};
use actix_rt::System; use actix_rt::System;
use actix_server::{Io, Server}; use actix_server::{Io, Server};
use actix_service::{fn_service, NewService}; use actix_service::{service_fn, NewService};
use futures::{future, Future}; use futures::{future, Future};
use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod}; use openssl::ssl::{SslAcceptor, SslFiletype, SslMethod};
use tokio_openssl::SslAcceptorExt; use tokio_openssl::SslAcceptorExt;
@ -54,14 +54,14 @@ fn main() -> io::Result<()> {
let acceptor = acceptor.clone(); let acceptor = acceptor.clone();
// service for converting incoming TcpStream to a SslStream<TcpStream> // service for converting incoming TcpStream to a SslStream<TcpStream>
fn_service(move |stream: Io<tokio_tcp::TcpStream>| { service_fn(move |stream: Io<tokio_tcp::TcpStream>| {
SslAcceptorExt::accept_async(&acceptor, stream.into_parts().0) SslAcceptorExt::accept_async(&acceptor, stream.into_parts().0)
.map_err(|e| println!("Openssl error: {}", e)) .map_err(|e| println!("Openssl error: {}", e))
}) })
// .and_then() combinator uses other service to convert incoming `Request` to a // .and_then() combinator uses other service to convert incoming `Request` to a
// `Response` and then uses that response as an input for next // `Response` and then uses that response as an input for next
// service. in this case, on success we use `logger` service // service. in this case, on success we use `logger` service
.and_then(fn_service(logger)) .and_then(logger)
// Next service counts number of connections // Next service counts number of connections
.and_then(move |_| { .and_then(move |_| {
let num = num.fetch_add(1, Ordering::Relaxed); let num = num.fetch_add(1, Ordering::Relaxed);