mirror of
https://github.com/fafhrd91/actix-net
synced 2024-11-27 19:12:56 +01:00
split service mod
This commit is contained in:
parent
0eae4d84b1
commit
89b8da724b
@ -115,14 +115,13 @@ where
|
|||||||
err: marker::PhantomData,
|
err: marker::PhantomData,
|
||||||
cfg: marker::PhantomData,
|
cfg: marker::PhantomData,
|
||||||
fut: marker::PhantomData,
|
fut: marker::PhantomData,
|
||||||
s: marker::PhantomData
|
s: marker::PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F, S, Err, Fut, Cfg>
|
impl<F, S, Err, Fut, Cfg>
|
||||||
IntoNewConfigurableService<Fn2NewConfigurableService<F, S, Err, Fut, Cfg>>
|
IntoNewConfigurableService<Fn2NewConfigurableService<F, S, Err, Fut, Cfg>> for F
|
||||||
for F
|
|
||||||
where
|
where
|
||||||
S: Service,
|
S: Service,
|
||||||
F: Fn(Cfg) -> Fut + 'static,
|
F: Fn(Cfg) -> Fut + 'static,
|
||||||
@ -144,7 +143,8 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F, S, Err, Fut, Cfg> NewConfigurableService for Fn2NewConfigurableService<F, S, Err, Fut, Cfg>
|
impl<F, S, Err, Fut, Cfg> NewConfigurableService
|
||||||
|
for Fn2NewConfigurableService<F, S, Err, Fut, Cfg>
|
||||||
where
|
where
|
||||||
S: Service,
|
S: Service,
|
||||||
F: Fn(Cfg) -> Fut,
|
F: Fn(Cfg) -> Fut,
|
||||||
|
@ -60,7 +60,7 @@ pub mod service;
|
|||||||
pub mod ssl;
|
pub mod ssl;
|
||||||
mod worker;
|
mod worker;
|
||||||
|
|
||||||
pub use configurable::{NewConfigurableService, IntoNewConfigurableService};
|
pub use configurable::{IntoNewConfigurableService, NewConfigurableService};
|
||||||
pub use connector::{Connector, ConnectorError};
|
pub use connector::{Connector, ConnectorError};
|
||||||
pub use server::Server;
|
pub use server::Server;
|
||||||
pub use service::{IntoNewService, IntoService, NewServiceExt};
|
pub use service::{IntoNewService, IntoService, NewServiceExt};
|
||||||
|
795
src/service.rs
795
src/service.rs
@ -1,795 +0,0 @@
|
|||||||
use std::cell::RefCell;
|
|
||||||
use std::marker;
|
|
||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
use futures::{future, future::FutureResult, Async, Future, IntoFuture, Poll};
|
|
||||||
use tower_service::{NewService, Service};
|
|
||||||
|
|
||||||
pub trait NewServiceExt: NewService {
|
|
||||||
fn and_then<F, B>(self, new_service: F) -> AndThenNewService<Self, B>
|
|
||||||
where
|
|
||||||
Self: Sized,
|
|
||||||
F: IntoNewService<B>,
|
|
||||||
B: NewService<
|
|
||||||
Request = Self::Response,
|
|
||||||
Error = Self::Error,
|
|
||||||
InitError = Self::InitError,
|
|
||||||
>,
|
|
||||||
{
|
|
||||||
AndThenNewService::new(self, new_service)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn map_err<F, E>(self, f: F) -> MapErrNewService<Self, F, E>
|
|
||||||
where
|
|
||||||
Self: Sized,
|
|
||||||
F: Fn(Self::Error) -> E,
|
|
||||||
{
|
|
||||||
MapErrNewService::new(self, f)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn map_init_err<F, E>(self, f: F) -> MapInitErr<Self, F, E>
|
|
||||||
where
|
|
||||||
Self: Sized,
|
|
||||||
F: Fn(Self::InitError) -> E,
|
|
||||||
{
|
|
||||||
MapInitErr::new(self, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: NewService> NewServiceExt for T {}
|
|
||||||
|
|
||||||
/// Trait for types that can be converted to a Service
|
|
||||||
pub trait IntoService<T>
|
|
||||||
where
|
|
||||||
T: Service,
|
|
||||||
{
|
|
||||||
/// Create service
|
|
||||||
fn into(self) -> T;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Trait for types that can be converted to a Service
|
|
||||||
pub trait IntoNewService<T>
|
|
||||||
where
|
|
||||||
T: NewService,
|
|
||||||
{
|
|
||||||
/// Create service
|
|
||||||
fn into_new_service(self) -> T;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> IntoService<T> for T
|
|
||||||
where
|
|
||||||
T: Service,
|
|
||||||
{
|
|
||||||
fn into(self) -> T {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> IntoNewService<T> for T
|
|
||||||
where
|
|
||||||
T: NewService,
|
|
||||||
{
|
|
||||||
fn into_new_service(self) -> T {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<F, Req, Resp, Err, Fut> IntoService<FnService<F, Req, Resp, Err, Fut>> for F
|
|
||||||
where
|
|
||||||
F: Fn(Req) -> Fut + 'static,
|
|
||||||
Fut: IntoFuture<Item = Resp, Error = Err>,
|
|
||||||
{
|
|
||||||
fn into(self) -> FnService<F, Req, Resp, Err, Fut> {
|
|
||||||
FnService::new(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct FnService<F, Req, Resp, E, Fut>
|
|
||||||
where
|
|
||||||
F: Fn(Req) -> Fut,
|
|
||||||
Fut: IntoFuture<Item = Resp, Error = E>,
|
|
||||||
{
|
|
||||||
f: F,
|
|
||||||
req: marker::PhantomData<Req>,
|
|
||||||
resp: marker::PhantomData<Resp>,
|
|
||||||
err: marker::PhantomData<E>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<F, Req, Resp, E, Fut> FnService<F, Req, Resp, E, Fut>
|
|
||||||
where
|
|
||||||
F: Fn(Req) -> Fut,
|
|
||||||
Fut: IntoFuture<Item = Resp, Error = E>,
|
|
||||||
{
|
|
||||||
pub fn new(f: F) -> Self {
|
|
||||||
FnService {
|
|
||||||
f,
|
|
||||||
req: marker::PhantomData,
|
|
||||||
resp: marker::PhantomData,
|
|
||||||
err: marker::PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<F, Req, Resp, E, Fut> Service for FnService<F, Req, Resp, E, Fut>
|
|
||||||
where
|
|
||||||
F: Fn(Req) -> Fut,
|
|
||||||
Fut: IntoFuture<Item = Resp, Error = E>,
|
|
||||||
{
|
|
||||||
type Request = Req;
|
|
||||||
type Response = Resp;
|
|
||||||
type Error = E;
|
|
||||||
type Future = Fut::Future;
|
|
||||||
|
|
||||||
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
|
||||||
Ok(Async::Ready(()))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn call(&mut self, req: Req) -> Self::Future {
|
|
||||||
(self.f)(req).into_future()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct FnNewService<F, Req, Resp, Err, IErr, Fut>
|
|
||||||
where
|
|
||||||
F: Fn(Req) -> Fut,
|
|
||||||
Fut: IntoFuture<Item = Resp, Error = Err>,
|
|
||||||
{
|
|
||||||
f: F,
|
|
||||||
req: marker::PhantomData<Req>,
|
|
||||||
resp: marker::PhantomData<Resp>,
|
|
||||||
err: marker::PhantomData<Err>,
|
|
||||||
ierr: marker::PhantomData<IErr>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<F, Req, Resp, Err, IErr, Fut> FnNewService<F, Req, Resp, Err, IErr, Fut>
|
|
||||||
where
|
|
||||||
F: Fn(Req) -> Fut + Clone,
|
|
||||||
Fut: IntoFuture<Item = Resp, Error = Err>,
|
|
||||||
{
|
|
||||||
fn new(f: F) -> Self {
|
|
||||||
FnNewService {
|
|
||||||
f,
|
|
||||||
req: marker::PhantomData,
|
|
||||||
resp: marker::PhantomData,
|
|
||||||
err: marker::PhantomData,
|
|
||||||
ierr: marker::PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<F, Req, Resp, Err, IErr, Fut> NewService for FnNewService<F, Req, Resp, Err, IErr, Fut>
|
|
||||||
where
|
|
||||||
F: Fn(Req) -> Fut + Clone,
|
|
||||||
Fut: IntoFuture<Item = Resp, Error = Err>,
|
|
||||||
{
|
|
||||||
type Request = Req;
|
|
||||||
type Response = Resp;
|
|
||||||
type Error = Err;
|
|
||||||
type Service = FnService<F, Req, Resp, Err, Fut>;
|
|
||||||
type InitError = IErr;
|
|
||||||
type Future = FutureResult<Self::Service, Self::InitError>;
|
|
||||||
|
|
||||||
fn new_service(&self) -> Self::Future {
|
|
||||||
future::ok(FnService::new(self.f.clone()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<F, Req, Resp, Err, IErr, Fut> IntoNewService<FnNewService<F, Req, Resp, Err, IErr, Fut>>
|
|
||||||
for F
|
|
||||||
where
|
|
||||||
F: Fn(Req) -> Fut + Clone + 'static,
|
|
||||||
Fut: IntoFuture<Item = Resp, Error = Err>,
|
|
||||||
{
|
|
||||||
fn into_new_service(self) -> FnNewService<F, Req, Resp, Err, IErr, Fut> {
|
|
||||||
FnNewService::new(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<F, Req, Resp, Err, IErr, Fut> Clone for FnNewService<F, Req, Resp, Err, IErr, Fut>
|
|
||||||
where
|
|
||||||
F: Fn(Req) -> Fut + Clone,
|
|
||||||
Fut: IntoFuture<Item = Resp, Error = Err>,
|
|
||||||
{
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
Self::new(self.f.clone())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct FnStateService<S, F, Req, Resp, Err, Fut>
|
|
||||||
where
|
|
||||||
F: Fn(&mut S, Req) -> Fut,
|
|
||||||
Fut: IntoFuture<Item = Resp, Error = Err>,
|
|
||||||
{
|
|
||||||
f: F,
|
|
||||||
state: S,
|
|
||||||
req: marker::PhantomData<Req>,
|
|
||||||
resp: marker::PhantomData<Resp>,
|
|
||||||
err: marker::PhantomData<Err>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S, F, Req, Resp, Err, Fut> FnStateService<S, F, Req, Resp, Err, Fut>
|
|
||||||
where
|
|
||||||
F: Fn(&mut S, Req) -> Fut,
|
|
||||||
Fut: IntoFuture<Item = Resp, Error = Err>,
|
|
||||||
{
|
|
||||||
pub fn new(state: S, f: F) -> Self {
|
|
||||||
FnStateService {
|
|
||||||
f,
|
|
||||||
state,
|
|
||||||
req: marker::PhantomData,
|
|
||||||
resp: marker::PhantomData,
|
|
||||||
err: marker::PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S, F, Req, Resp, Err, Fut> Service for FnStateService<S, F, Req, Resp, Err, Fut>
|
|
||||||
where
|
|
||||||
F: Fn(&mut S, Req) -> Fut,
|
|
||||||
Fut: IntoFuture<Item = Resp, Error = Err>,
|
|
||||||
{
|
|
||||||
type Request = Req;
|
|
||||||
type Response = Resp;
|
|
||||||
type Error = Err;
|
|
||||||
type Future = Fut::Future;
|
|
||||||
|
|
||||||
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
|
||||||
Ok(Async::Ready(()))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn call(&mut self, req: Req) -> Self::Future {
|
|
||||||
(self.f)(&mut self.state, req).into_future()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// `NewService` for state and handler functions
|
|
||||||
pub struct FnStateNewService<S, F1, F2, Req, Resp, Err1, Err2, Fut1, Fut2> {
|
|
||||||
f: F1,
|
|
||||||
state: F2,
|
|
||||||
s: marker::PhantomData<S>,
|
|
||||||
req: marker::PhantomData<Req>,
|
|
||||||
resp: marker::PhantomData<Resp>,
|
|
||||||
err1: marker::PhantomData<Err1>,
|
|
||||||
err2: marker::PhantomData<Err2>,
|
|
||||||
fut1: marker::PhantomData<Fut1>,
|
|
||||||
fut2: marker::PhantomData<Fut2>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S, F1, F2, Req, Resp, Err1, Err2, Fut1, Fut2>
|
|
||||||
FnStateNewService<S, F1, F2, Req, Resp, Err1, Err2, Fut1, Fut2>
|
|
||||||
{
|
|
||||||
fn new(f: F1, state: F2) -> Self {
|
|
||||||
FnStateNewService {
|
|
||||||
f,
|
|
||||||
state,
|
|
||||||
s: marker::PhantomData,
|
|
||||||
req: marker::PhantomData,
|
|
||||||
resp: marker::PhantomData,
|
|
||||||
err1: marker::PhantomData,
|
|
||||||
err2: marker::PhantomData,
|
|
||||||
fut1: marker::PhantomData,
|
|
||||||
fut2: marker::PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S, F1, F2, Req, Resp, Err1, Err2, Fut1, Fut2> NewService
|
|
||||||
for FnStateNewService<S, F1, F2, Req, Resp, Err1, Err2, Fut1, Fut2>
|
|
||||||
where
|
|
||||||
S: 'static,
|
|
||||||
F1: Fn(&mut S, Req) -> Fut1 + Clone + 'static,
|
|
||||||
F2: Fn() -> Fut2,
|
|
||||||
Fut1: IntoFuture<Item = Resp, Error = Err1> + 'static,
|
|
||||||
Fut2: IntoFuture<Item = S, Error = Err2> + 'static,
|
|
||||||
Req: 'static,
|
|
||||||
Resp: 'static,
|
|
||||||
Err1: 'static,
|
|
||||||
Err2: 'static,
|
|
||||||
{
|
|
||||||
type Request = Req;
|
|
||||||
type Response = Resp;
|
|
||||||
type Error = Err1;
|
|
||||||
type Service = FnStateService<S, F1, Req, Resp, Err1, Fut1>;
|
|
||||||
type InitError = Err2;
|
|
||||||
type Future = Box<Future<Item = Self::Service, Error = Self::InitError>>;
|
|
||||||
|
|
||||||
fn new_service(&self) -> Self::Future {
|
|
||||||
let f = self.f.clone();
|
|
||||||
Box::new(
|
|
||||||
(self.state)()
|
|
||||||
.into_future()
|
|
||||||
.and_then(move |state| Ok(FnStateService::new(state, f))),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S, F1, F2, Req, Resp, Err1, Err2, Fut1, Fut2>
|
|
||||||
IntoNewService<FnStateNewService<S, F1, F2, Req, Resp, Err1, Err2, Fut1, Fut2>> for (F1, F2)
|
|
||||||
where
|
|
||||||
S: 'static,
|
|
||||||
F1: Fn(&mut S, Req) -> Fut1 + Clone + 'static,
|
|
||||||
F2: Fn() -> Fut2,
|
|
||||||
Fut1: IntoFuture<Item = Resp, Error = Err1> + 'static,
|
|
||||||
Fut2: IntoFuture<Item = S, Error = Err2> + 'static,
|
|
||||||
Req: 'static,
|
|
||||||
Resp: 'static,
|
|
||||||
Err1: 'static,
|
|
||||||
Err2: 'static,
|
|
||||||
{
|
|
||||||
fn into_new_service(
|
|
||||||
self,
|
|
||||||
) -> FnStateNewService<S, F1, F2, Req, Resp, Err1, Err2, Fut1, Fut2> {
|
|
||||||
FnStateNewService::new(self.0, self.1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S, F1, F2, Req, Resp, Err1, Err2, Fut1, Fut2> Clone
|
|
||||||
for FnStateNewService<S, F1, F2, Req, Resp, Err1, Err2, Fut1, Fut2>
|
|
||||||
where
|
|
||||||
F1: Fn(&mut S, Req) -> Fut1 + Clone + 'static,
|
|
||||||
F2: Fn() -> Fut2 + Clone,
|
|
||||||
Fut1: IntoFuture<Item = Resp, Error = Err1>,
|
|
||||||
Fut2: IntoFuture<Item = S, Error = Err2>,
|
|
||||||
{
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
Self::new(self.f.clone(), self.state.clone())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// `AndThen` service combinator
|
|
||||||
pub struct AndThen<A, B> {
|
|
||||||
a: A,
|
|
||||||
b: Rc<RefCell<B>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<A, B> AndThen<A, B>
|
|
||||||
where
|
|
||||||
A: Service,
|
|
||||||
A::Error: Into<B::Error>,
|
|
||||||
B: Service<Request = A::Response>,
|
|
||||||
{
|
|
||||||
/// Create new `AndThen` combinator
|
|
||||||
pub fn new(a: A, b: B) -> Self {
|
|
||||||
Self {
|
|
||||||
a,
|
|
||||||
b: Rc::new(RefCell::new(b)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<A, B> Service for AndThen<A, B>
|
|
||||||
where
|
|
||||||
A: Service,
|
|
||||||
A::Error: Into<B::Error>,
|
|
||||||
B: Service<Request = A::Response>,
|
|
||||||
{
|
|
||||||
type Request = A::Request;
|
|
||||||
type Response = B::Response;
|
|
||||||
type Error = B::Error;
|
|
||||||
type Future = AndThenFuture<A, B>;
|
|
||||||
|
|
||||||
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
|
||||||
match self.a.poll_ready() {
|
|
||||||
Ok(Async::Ready(_)) => self.b.borrow_mut().poll_ready(),
|
|
||||||
Ok(Async::NotReady) => Ok(Async::NotReady),
|
|
||||||
Err(err) => Err(err.into()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn call(&mut self, req: Self::Request) -> Self::Future {
|
|
||||||
AndThenFuture::new(self.a.call(req), self.b.clone())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct AndThenFuture<A, B>
|
|
||||||
where
|
|
||||||
A: Service,
|
|
||||||
A::Error: Into<B::Error>,
|
|
||||||
B: Service<Request = A::Response>,
|
|
||||||
{
|
|
||||||
b: Rc<RefCell<B>>,
|
|
||||||
fut_b: Option<B::Future>,
|
|
||||||
fut_a: A::Future,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<A, B> AndThenFuture<A, B>
|
|
||||||
where
|
|
||||||
A: Service,
|
|
||||||
A::Error: Into<B::Error>,
|
|
||||||
B: Service<Request = A::Response>,
|
|
||||||
{
|
|
||||||
fn new(fut_a: A::Future, b: Rc<RefCell<B>>) -> Self {
|
|
||||||
AndThenFuture {
|
|
||||||
b,
|
|
||||||
fut_a,
|
|
||||||
fut_b: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<A, B> Future for AndThenFuture<A, B>
|
|
||||||
where
|
|
||||||
A: Service,
|
|
||||||
A::Error: Into<B::Error>,
|
|
||||||
B: Service<Request = A::Response>,
|
|
||||||
{
|
|
||||||
type Item = B::Response;
|
|
||||||
type Error = B::Error;
|
|
||||||
|
|
||||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
|
||||||
if let Some(ref mut fut) = self.fut_b {
|
|
||||||
return fut.poll();
|
|
||||||
}
|
|
||||||
|
|
||||||
match self.fut_a.poll() {
|
|
||||||
Ok(Async::Ready(resp)) => {
|
|
||||||
self.fut_b = Some(self.b.borrow_mut().call(resp));
|
|
||||||
self.poll()
|
|
||||||
}
|
|
||||||
Ok(Async::NotReady) => Ok(Async::NotReady),
|
|
||||||
Err(err) => Err(err.into()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// `AndThenNewService` new service combinator
|
|
||||||
pub struct AndThenNewService<A, B> {
|
|
||||||
a: A,
|
|
||||||
b: B,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<A, B> AndThenNewService<A, B>
|
|
||||||
where
|
|
||||||
A: NewService,
|
|
||||||
B: NewService,
|
|
||||||
{
|
|
||||||
/// Create new `AndThen` combinator
|
|
||||||
pub fn new<F: IntoNewService<B>>(a: A, f: F) -> Self {
|
|
||||||
Self {
|
|
||||||
a,
|
|
||||||
b: f.into_new_service(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<A, B> NewService for AndThenNewService<A, B>
|
|
||||||
where
|
|
||||||
A: NewService<Response = B::Request, InitError = B::InitError>,
|
|
||||||
A::Error: Into<B::Error>,
|
|
||||||
B: NewService,
|
|
||||||
{
|
|
||||||
type Request = A::Request;
|
|
||||||
type Response = B::Response;
|
|
||||||
type Error = B::Error;
|
|
||||||
type Service = AndThen<A::Service, B::Service>;
|
|
||||||
|
|
||||||
type InitError = A::InitError;
|
|
||||||
type Future = AndThenNewServiceFuture<A, B>;
|
|
||||||
|
|
||||||
fn new_service(&self) -> Self::Future {
|
|
||||||
AndThenNewServiceFuture::new(self.a.new_service(), self.b.new_service())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<A, B> Clone for AndThenNewService<A, B>
|
|
||||||
where
|
|
||||||
A: NewService<Response = B::Request, InitError = B::InitError> + Clone,
|
|
||||||
A::Error: Into<B::Error>,
|
|
||||||
B: NewService + Clone,
|
|
||||||
{
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
Self {
|
|
||||||
a: self.a.clone(),
|
|
||||||
b: self.b.clone(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct AndThenNewServiceFuture<A, B>
|
|
||||||
where
|
|
||||||
A: NewService,
|
|
||||||
B: NewService,
|
|
||||||
{
|
|
||||||
fut_b: B::Future,
|
|
||||||
fut_a: A::Future,
|
|
||||||
a: Option<A::Service>,
|
|
||||||
b: Option<B::Service>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<A, B> AndThenNewServiceFuture<A, B>
|
|
||||||
where
|
|
||||||
A: NewService,
|
|
||||||
B: NewService,
|
|
||||||
{
|
|
||||||
fn new(fut_a: A::Future, fut_b: B::Future) -> Self {
|
|
||||||
AndThenNewServiceFuture {
|
|
||||||
fut_a,
|
|
||||||
fut_b,
|
|
||||||
a: None,
|
|
||||||
b: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<A, B> Future for AndThenNewServiceFuture<A, B>
|
|
||||||
where
|
|
||||||
A: NewService,
|
|
||||||
A::Error: Into<B::Error>,
|
|
||||||
B: NewService<Request = A::Response, InitError = A::InitError>,
|
|
||||||
{
|
|
||||||
type Item = AndThen<A::Service, B::Service>;
|
|
||||||
type Error = B::InitError;
|
|
||||||
|
|
||||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
|
||||||
if self.a.is_none() {
|
|
||||||
if let Async::Ready(service) = self.fut_a.poll()? {
|
|
||||||
self.a = Some(service);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.b.is_none() {
|
|
||||||
if let Async::Ready(service) = self.fut_b.poll()? {
|
|
||||||
self.b = Some(service);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.a.is_some() && self.b.is_some() {
|
|
||||||
Ok(Async::Ready(AndThen::new(
|
|
||||||
self.a.take().unwrap(),
|
|
||||||
self.b.take().unwrap(),
|
|
||||||
)))
|
|
||||||
} else {
|
|
||||||
Ok(Async::NotReady)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// `MapErr` service combinator
|
|
||||||
pub struct MapErr<A, F, E> {
|
|
||||||
a: A,
|
|
||||||
f: F,
|
|
||||||
e: marker::PhantomData<E>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<A, F, E> MapErr<A, F, E>
|
|
||||||
where
|
|
||||||
A: Service,
|
|
||||||
F: Fn(A::Error) -> E,
|
|
||||||
{
|
|
||||||
/// Create new `MapErr` combinator
|
|
||||||
pub fn new(a: A, f: F) -> Self {
|
|
||||||
Self {
|
|
||||||
a,
|
|
||||||
f,
|
|
||||||
e: marker::PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<A, F, E> Service for MapErr<A, F, E>
|
|
||||||
where
|
|
||||||
A: Service,
|
|
||||||
F: Fn(A::Error) -> E,
|
|
||||||
F: Clone,
|
|
||||||
{
|
|
||||||
type Request = A::Request;
|
|
||||||
type Response = A::Response;
|
|
||||||
type Error = E;
|
|
||||||
type Future = MapErrFuture<A, F, E>;
|
|
||||||
|
|
||||||
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
|
||||||
self.a.poll_ready().map_err(&self.f)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn call(&mut self, req: Self::Request) -> Self::Future {
|
|
||||||
MapErrFuture::new(self.a.call(req), self.f.clone())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct MapErrFuture<A, F, E>
|
|
||||||
where
|
|
||||||
A: Service,
|
|
||||||
F: Fn(A::Error) -> E,
|
|
||||||
{
|
|
||||||
f: F,
|
|
||||||
fut: A::Future,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<A, F, E> MapErrFuture<A, F, E>
|
|
||||||
where
|
|
||||||
A: Service,
|
|
||||||
F: Fn(A::Error) -> E,
|
|
||||||
{
|
|
||||||
fn new(fut: A::Future, f: F) -> Self {
|
|
||||||
MapErrFuture { f, fut }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<A, F, E> Future for MapErrFuture<A, F, E>
|
|
||||||
where
|
|
||||||
A: Service,
|
|
||||||
F: Fn(A::Error) -> E,
|
|
||||||
{
|
|
||||||
type Item = A::Response;
|
|
||||||
type Error = E;
|
|
||||||
|
|
||||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
|
||||||
self.fut.poll().map_err(&self.f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// `MapErrNewService` new service combinator
|
|
||||||
pub struct MapErrNewService<A, F, E> {
|
|
||||||
a: A,
|
|
||||||
f: F,
|
|
||||||
e: marker::PhantomData<E>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<A, F, E> MapErrNewService<A, F, E>
|
|
||||||
where
|
|
||||||
A: NewService,
|
|
||||||
F: Fn(A::Error) -> E,
|
|
||||||
{
|
|
||||||
/// Create new `MapErr` new service instance
|
|
||||||
pub fn new(a: A, f: F) -> Self {
|
|
||||||
Self {
|
|
||||||
a,
|
|
||||||
f,
|
|
||||||
e: marker::PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<A, F, E> Clone for MapErrNewService<A, F, E>
|
|
||||||
where
|
|
||||||
A: NewService + Clone,
|
|
||||||
F: Fn(A::Error) -> E + Clone,
|
|
||||||
{
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
Self {
|
|
||||||
a: self.a.clone(),
|
|
||||||
f: self.f.clone(),
|
|
||||||
e: marker::PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<A, F, E> NewService for MapErrNewService<A, F, E>
|
|
||||||
where
|
|
||||||
A: NewService + Clone,
|
|
||||||
F: Fn(A::Error) -> E + Clone,
|
|
||||||
{
|
|
||||||
type Request = A::Request;
|
|
||||||
type Response = A::Response;
|
|
||||||
type Error = E;
|
|
||||||
type Service = MapErr<A::Service, F, E>;
|
|
||||||
|
|
||||||
type InitError = A::InitError;
|
|
||||||
type Future = MapErrNewServiceFuture<A, F, E>;
|
|
||||||
|
|
||||||
fn new_service(&self) -> Self::Future {
|
|
||||||
MapErrNewServiceFuture::new(self.a.new_service(), self.f.clone())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct MapErrNewServiceFuture<A, F, E>
|
|
||||||
where
|
|
||||||
A: NewService,
|
|
||||||
F: Fn(A::Error) -> E,
|
|
||||||
{
|
|
||||||
fut: A::Future,
|
|
||||||
f: F,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<A, F, E> MapErrNewServiceFuture<A, F, E>
|
|
||||||
where
|
|
||||||
A: NewService,
|
|
||||||
F: Fn(A::Error) -> E,
|
|
||||||
{
|
|
||||||
fn new(fut: A::Future, f: F) -> Self {
|
|
||||||
MapErrNewServiceFuture { f, fut }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<A, F, E> Future for MapErrNewServiceFuture<A, F, E>
|
|
||||||
where
|
|
||||||
A: NewService,
|
|
||||||
F: Fn(A::Error) -> E + Clone,
|
|
||||||
{
|
|
||||||
type Item = MapErr<A::Service, F, E>;
|
|
||||||
type Error = A::InitError;
|
|
||||||
|
|
||||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
|
||||||
if let Async::Ready(service) = self.fut.poll()? {
|
|
||||||
Ok(Async::Ready(MapErr::new(service, self.f.clone())))
|
|
||||||
} else {
|
|
||||||
Ok(Async::NotReady)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// `MapInitErr` service combinator
|
|
||||||
pub struct MapInitErr<A, F, E> {
|
|
||||||
a: A,
|
|
||||||
f: F,
|
|
||||||
e: marker::PhantomData<E>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<A, F, E> MapInitErr<A, F, E>
|
|
||||||
where
|
|
||||||
A: NewService,
|
|
||||||
F: Fn(A::InitError) -> E,
|
|
||||||
{
|
|
||||||
/// Create new `MapInitErr` combinator
|
|
||||||
pub fn new(a: A, f: F) -> Self {
|
|
||||||
Self {
|
|
||||||
a,
|
|
||||||
f,
|
|
||||||
e: marker::PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<A, F, E> Clone for MapInitErr<A, F, E>
|
|
||||||
where
|
|
||||||
A: NewService + Clone,
|
|
||||||
F: Fn(A::InitError) -> E + Clone,
|
|
||||||
{
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
Self {
|
|
||||||
a: self.a.clone(),
|
|
||||||
f: self.f.clone(),
|
|
||||||
e: marker::PhantomData,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<A, F, E> NewService for MapInitErr<A, F, E>
|
|
||||||
where
|
|
||||||
A: NewService,
|
|
||||||
F: Fn(A::InitError) -> E + Clone,
|
|
||||||
{
|
|
||||||
type Request = A::Request;
|
|
||||||
type Response = A::Response;
|
|
||||||
type Error = A::Error;
|
|
||||||
type Service = A::Service;
|
|
||||||
|
|
||||||
type InitError = E;
|
|
||||||
type Future = MapInitErrFuture<A, F, E>;
|
|
||||||
|
|
||||||
fn new_service(&self) -> Self::Future {
|
|
||||||
MapInitErrFuture::new(self.a.new_service(), self.f.clone())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct MapInitErrFuture<A, F, E>
|
|
||||||
where
|
|
||||||
A: NewService,
|
|
||||||
F: Fn(A::InitError) -> E,
|
|
||||||
{
|
|
||||||
f: F,
|
|
||||||
fut: A::Future,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<A, F, E> MapInitErrFuture<A, F, E>
|
|
||||||
where
|
|
||||||
A: NewService,
|
|
||||||
F: Fn(A::InitError) -> E,
|
|
||||||
{
|
|
||||||
fn new(fut: A::Future, f: F) -> Self {
|
|
||||||
MapInitErrFuture { f, fut }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<A, F, E> Future for MapInitErrFuture<A, F, E>
|
|
||||||
where
|
|
||||||
A: NewService,
|
|
||||||
F: Fn(A::InitError) -> E,
|
|
||||||
{
|
|
||||||
type Item = A::Service;
|
|
||||||
type Error = E;
|
|
||||||
|
|
||||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
|
||||||
self.fut.poll().map_err(&self.f)
|
|
||||||
}
|
|
||||||
}
|
|
215
src/service/and_then.rs
Normal file
215
src/service/and_then.rs
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
use std::cell::RefCell;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
use futures::{Async, Future, Poll};
|
||||||
|
use tower_service::{NewService, Service};
|
||||||
|
|
||||||
|
use super::IntoNewService;
|
||||||
|
|
||||||
|
/// `AndThen` service combinator
|
||||||
|
pub struct AndThen<A, B> {
|
||||||
|
a: A,
|
||||||
|
b: Rc<RefCell<B>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A, B> AndThen<A, B>
|
||||||
|
where
|
||||||
|
A: Service,
|
||||||
|
A::Error: Into<B::Error>,
|
||||||
|
B: Service<Request = A::Response>,
|
||||||
|
{
|
||||||
|
/// Create new `AndThen` combinator
|
||||||
|
pub fn new(a: A, b: B) -> Self {
|
||||||
|
Self {
|
||||||
|
a,
|
||||||
|
b: Rc::new(RefCell::new(b)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A, B> Service for AndThen<A, B>
|
||||||
|
where
|
||||||
|
A: Service,
|
||||||
|
A::Error: Into<B::Error>,
|
||||||
|
B: Service<Request = A::Response>,
|
||||||
|
{
|
||||||
|
type Request = A::Request;
|
||||||
|
type Response = B::Response;
|
||||||
|
type Error = B::Error;
|
||||||
|
type Future = AndThenFuture<A, B>;
|
||||||
|
|
||||||
|
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||||
|
match self.a.poll_ready() {
|
||||||
|
Ok(Async::Ready(_)) => self.b.borrow_mut().poll_ready(),
|
||||||
|
Ok(Async::NotReady) => Ok(Async::NotReady),
|
||||||
|
Err(err) => Err(err.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn call(&mut self, req: Self::Request) -> Self::Future {
|
||||||
|
AndThenFuture::new(self.a.call(req), self.b.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct AndThenFuture<A, B>
|
||||||
|
where
|
||||||
|
A: Service,
|
||||||
|
A::Error: Into<B::Error>,
|
||||||
|
B: Service<Request = A::Response>,
|
||||||
|
{
|
||||||
|
b: Rc<RefCell<B>>,
|
||||||
|
fut_b: Option<B::Future>,
|
||||||
|
fut_a: A::Future,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A, B> AndThenFuture<A, B>
|
||||||
|
where
|
||||||
|
A: Service,
|
||||||
|
A::Error: Into<B::Error>,
|
||||||
|
B: Service<Request = A::Response>,
|
||||||
|
{
|
||||||
|
fn new(fut_a: A::Future, b: Rc<RefCell<B>>) -> Self {
|
||||||
|
AndThenFuture {
|
||||||
|
b,
|
||||||
|
fut_a,
|
||||||
|
fut_b: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A, B> Future for AndThenFuture<A, B>
|
||||||
|
where
|
||||||
|
A: Service,
|
||||||
|
A::Error: Into<B::Error>,
|
||||||
|
B: Service<Request = A::Response>,
|
||||||
|
{
|
||||||
|
type Item = B::Response;
|
||||||
|
type Error = B::Error;
|
||||||
|
|
||||||
|
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||||
|
if let Some(ref mut fut) = self.fut_b {
|
||||||
|
return fut.poll();
|
||||||
|
}
|
||||||
|
|
||||||
|
match self.fut_a.poll() {
|
||||||
|
Ok(Async::Ready(resp)) => {
|
||||||
|
self.fut_b = Some(self.b.borrow_mut().call(resp));
|
||||||
|
self.poll()
|
||||||
|
}
|
||||||
|
Ok(Async::NotReady) => Ok(Async::NotReady),
|
||||||
|
Err(err) => Err(err.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `AndThenNewService` new service combinator
|
||||||
|
pub struct AndThenNewService<A, B> {
|
||||||
|
a: A,
|
||||||
|
b: B,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A, B> AndThenNewService<A, B>
|
||||||
|
where
|
||||||
|
A: NewService,
|
||||||
|
B: NewService,
|
||||||
|
{
|
||||||
|
/// Create new `AndThen` combinator
|
||||||
|
pub fn new<F: IntoNewService<B>>(a: A, f: F) -> Self {
|
||||||
|
Self {
|
||||||
|
a,
|
||||||
|
b: f.into_new_service(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A, B> NewService for AndThenNewService<A, B>
|
||||||
|
where
|
||||||
|
A: NewService<Response = B::Request, InitError = B::InitError>,
|
||||||
|
A::Error: Into<B::Error>,
|
||||||
|
B: NewService,
|
||||||
|
{
|
||||||
|
type Request = A::Request;
|
||||||
|
type Response = B::Response;
|
||||||
|
type Error = B::Error;
|
||||||
|
type Service = AndThen<A::Service, B::Service>;
|
||||||
|
|
||||||
|
type InitError = A::InitError;
|
||||||
|
type Future = AndThenNewServiceFuture<A, B>;
|
||||||
|
|
||||||
|
fn new_service(&self) -> Self::Future {
|
||||||
|
AndThenNewServiceFuture::new(self.a.new_service(), self.b.new_service())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A, B> Clone for AndThenNewService<A, B>
|
||||||
|
where
|
||||||
|
A: NewService<Response = B::Request, InitError = B::InitError> + Clone,
|
||||||
|
A::Error: Into<B::Error>,
|
||||||
|
B: NewService + Clone,
|
||||||
|
{
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Self {
|
||||||
|
a: self.a.clone(),
|
||||||
|
b: self.b.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct AndThenNewServiceFuture<A, B>
|
||||||
|
where
|
||||||
|
A: NewService,
|
||||||
|
B: NewService,
|
||||||
|
{
|
||||||
|
fut_b: B::Future,
|
||||||
|
fut_a: A::Future,
|
||||||
|
a: Option<A::Service>,
|
||||||
|
b: Option<B::Service>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A, B> AndThenNewServiceFuture<A, B>
|
||||||
|
where
|
||||||
|
A: NewService,
|
||||||
|
B: NewService,
|
||||||
|
{
|
||||||
|
fn new(fut_a: A::Future, fut_b: B::Future) -> Self {
|
||||||
|
AndThenNewServiceFuture {
|
||||||
|
fut_a,
|
||||||
|
fut_b,
|
||||||
|
a: None,
|
||||||
|
b: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A, B> Future for AndThenNewServiceFuture<A, B>
|
||||||
|
where
|
||||||
|
A: NewService,
|
||||||
|
A::Error: Into<B::Error>,
|
||||||
|
B: NewService<Request = A::Response, InitError = A::InitError>,
|
||||||
|
{
|
||||||
|
type Item = AndThen<A::Service, B::Service>;
|
||||||
|
type Error = B::InitError;
|
||||||
|
|
||||||
|
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||||
|
if self.a.is_none() {
|
||||||
|
if let Async::Ready(service) = self.fut_a.poll()? {
|
||||||
|
self.a = Some(service);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.b.is_none() {
|
||||||
|
if let Async::Ready(service) = self.fut_b.poll()? {
|
||||||
|
self.b = Some(service);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.a.is_some() && self.b.is_some() {
|
||||||
|
Ok(Async::Ready(AndThen::new(
|
||||||
|
self.a.take().unwrap(),
|
||||||
|
self.b.take().unwrap(),
|
||||||
|
)))
|
||||||
|
} else {
|
||||||
|
Ok(Async::NotReady)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
120
src/service/fn_service.rs
Normal file
120
src/service/fn_service.rs
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
use std::marker;
|
||||||
|
|
||||||
|
use futures::{
|
||||||
|
future::{ok, FutureResult},
|
||||||
|
Async, IntoFuture, Poll,
|
||||||
|
};
|
||||||
|
use tower_service::{NewService, Service};
|
||||||
|
|
||||||
|
use super::IntoNewService;
|
||||||
|
|
||||||
|
pub struct FnService<F, Req, Resp, E, Fut>
|
||||||
|
where
|
||||||
|
F: Fn(Req) -> Fut,
|
||||||
|
Fut: IntoFuture<Item = Resp, Error = E>,
|
||||||
|
{
|
||||||
|
f: F,
|
||||||
|
req: marker::PhantomData<Req>,
|
||||||
|
resp: marker::PhantomData<Resp>,
|
||||||
|
err: marker::PhantomData<E>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F, Req, Resp, E, Fut> FnService<F, Req, Resp, E, Fut>
|
||||||
|
where
|
||||||
|
F: Fn(Req) -> Fut,
|
||||||
|
Fut: IntoFuture<Item = Resp, Error = E>,
|
||||||
|
{
|
||||||
|
pub fn new(f: F) -> Self {
|
||||||
|
FnService {
|
||||||
|
f,
|
||||||
|
req: marker::PhantomData,
|
||||||
|
resp: marker::PhantomData,
|
||||||
|
err: marker::PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F, Req, Resp, E, Fut> Service for FnService<F, Req, Resp, E, Fut>
|
||||||
|
where
|
||||||
|
F: Fn(Req) -> Fut,
|
||||||
|
Fut: IntoFuture<Item = Resp, Error = E>,
|
||||||
|
{
|
||||||
|
type Request = Req;
|
||||||
|
type Response = Resp;
|
||||||
|
type Error = E;
|
||||||
|
type Future = Fut::Future;
|
||||||
|
|
||||||
|
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||||
|
Ok(Async::Ready(()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn call(&mut self, req: Req) -> Self::Future {
|
||||||
|
(self.f)(req).into_future()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct FnNewService<F, Req, Resp, Err, IErr, Fut>
|
||||||
|
where
|
||||||
|
F: Fn(Req) -> Fut,
|
||||||
|
Fut: IntoFuture<Item = Resp, Error = Err>,
|
||||||
|
{
|
||||||
|
f: F,
|
||||||
|
req: marker::PhantomData<Req>,
|
||||||
|
resp: marker::PhantomData<Resp>,
|
||||||
|
err: marker::PhantomData<Err>,
|
||||||
|
ierr: marker::PhantomData<IErr>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F, Req, Resp, Err, IErr, Fut> FnNewService<F, Req, Resp, Err, IErr, Fut>
|
||||||
|
where
|
||||||
|
F: Fn(Req) -> Fut + Clone,
|
||||||
|
Fut: IntoFuture<Item = Resp, Error = Err>,
|
||||||
|
{
|
||||||
|
fn new(f: F) -> Self {
|
||||||
|
FnNewService {
|
||||||
|
f,
|
||||||
|
req: marker::PhantomData,
|
||||||
|
resp: marker::PhantomData,
|
||||||
|
err: marker::PhantomData,
|
||||||
|
ierr: marker::PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F, Req, Resp, Err, IErr, Fut> NewService for FnNewService<F, Req, Resp, Err, IErr, Fut>
|
||||||
|
where
|
||||||
|
F: Fn(Req) -> Fut + Clone,
|
||||||
|
Fut: IntoFuture<Item = Resp, Error = Err>,
|
||||||
|
{
|
||||||
|
type Request = Req;
|
||||||
|
type Response = Resp;
|
||||||
|
type Error = Err;
|
||||||
|
type Service = FnService<F, Req, Resp, Err, Fut>;
|
||||||
|
type InitError = IErr;
|
||||||
|
type Future = FutureResult<Self::Service, Self::InitError>;
|
||||||
|
|
||||||
|
fn new_service(&self) -> Self::Future {
|
||||||
|
ok(FnService::new(self.f.clone()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F, Req, Resp, Err, IErr, Fut> IntoNewService<FnNewService<F, Req, Resp, Err, IErr, Fut>>
|
||||||
|
for F
|
||||||
|
where
|
||||||
|
F: Fn(Req) -> Fut + Clone + 'static,
|
||||||
|
Fut: IntoFuture<Item = Resp, Error = Err>,
|
||||||
|
{
|
||||||
|
fn into_new_service(self) -> FnNewService<F, Req, Resp, Err, IErr, Fut> {
|
||||||
|
FnNewService::new(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F, Req, Resp, Err, IErr, Fut> Clone for FnNewService<F, Req, Resp, Err, IErr, Fut>
|
||||||
|
where
|
||||||
|
F: Fn(Req) -> Fut + Clone,
|
||||||
|
Fut: IntoFuture<Item = Resp, Error = Err>,
|
||||||
|
{
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Self::new(self.f.clone())
|
||||||
|
}
|
||||||
|
}
|
147
src/service/fn_state_service.rs
Normal file
147
src/service/fn_state_service.rs
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
use std::marker;
|
||||||
|
|
||||||
|
use futures::{Async, Future, IntoFuture, Poll};
|
||||||
|
use tower_service::{NewService, Service};
|
||||||
|
|
||||||
|
use super::IntoNewService;
|
||||||
|
|
||||||
|
pub struct FnStateService<S, F, Req, Resp, Err, Fut>
|
||||||
|
where
|
||||||
|
F: Fn(&mut S, Req) -> Fut,
|
||||||
|
Fut: IntoFuture<Item = Resp, Error = Err>,
|
||||||
|
{
|
||||||
|
f: F,
|
||||||
|
state: S,
|
||||||
|
req: marker::PhantomData<Req>,
|
||||||
|
resp: marker::PhantomData<Resp>,
|
||||||
|
err: marker::PhantomData<Err>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S, F, Req, Resp, Err, Fut> FnStateService<S, F, Req, Resp, Err, Fut>
|
||||||
|
where
|
||||||
|
F: Fn(&mut S, Req) -> Fut,
|
||||||
|
Fut: IntoFuture<Item = Resp, Error = Err>,
|
||||||
|
{
|
||||||
|
pub fn new(state: S, f: F) -> Self {
|
||||||
|
FnStateService {
|
||||||
|
f,
|
||||||
|
state,
|
||||||
|
req: marker::PhantomData,
|
||||||
|
resp: marker::PhantomData,
|
||||||
|
err: marker::PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S, F, Req, Resp, Err, Fut> Service for FnStateService<S, F, Req, Resp, Err, Fut>
|
||||||
|
where
|
||||||
|
F: Fn(&mut S, Req) -> Fut,
|
||||||
|
Fut: IntoFuture<Item = Resp, Error = Err>,
|
||||||
|
{
|
||||||
|
type Request = Req;
|
||||||
|
type Response = Resp;
|
||||||
|
type Error = Err;
|
||||||
|
type Future = Fut::Future;
|
||||||
|
|
||||||
|
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||||
|
Ok(Async::Ready(()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn call(&mut self, req: Req) -> Self::Future {
|
||||||
|
(self.f)(&mut self.state, req).into_future()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `NewService` for state and handler functions
|
||||||
|
pub struct FnStateNewService<S, F1, F2, Req, Resp, Err1, Err2, Fut1, Fut2> {
|
||||||
|
f: F1,
|
||||||
|
state: F2,
|
||||||
|
s: marker::PhantomData<S>,
|
||||||
|
req: marker::PhantomData<Req>,
|
||||||
|
resp: marker::PhantomData<Resp>,
|
||||||
|
err1: marker::PhantomData<Err1>,
|
||||||
|
err2: marker::PhantomData<Err2>,
|
||||||
|
fut1: marker::PhantomData<Fut1>,
|
||||||
|
fut2: marker::PhantomData<Fut2>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S, F1, F2, Req, Resp, Err1, Err2, Fut1, Fut2>
|
||||||
|
FnStateNewService<S, F1, F2, Req, Resp, Err1, Err2, Fut1, Fut2>
|
||||||
|
{
|
||||||
|
fn new(f: F1, state: F2) -> Self {
|
||||||
|
FnStateNewService {
|
||||||
|
f,
|
||||||
|
state,
|
||||||
|
s: marker::PhantomData,
|
||||||
|
req: marker::PhantomData,
|
||||||
|
resp: marker::PhantomData,
|
||||||
|
err1: marker::PhantomData,
|
||||||
|
err2: marker::PhantomData,
|
||||||
|
fut1: marker::PhantomData,
|
||||||
|
fut2: marker::PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S, F1, F2, Req, Resp, Err1, Err2, Fut1, Fut2> NewService
|
||||||
|
for FnStateNewService<S, F1, F2, Req, Resp, Err1, Err2, Fut1, Fut2>
|
||||||
|
where
|
||||||
|
S: 'static,
|
||||||
|
F1: Fn(&mut S, Req) -> Fut1 + Clone + 'static,
|
||||||
|
F2: Fn() -> Fut2,
|
||||||
|
Fut1: IntoFuture<Item = Resp, Error = Err1> + 'static,
|
||||||
|
Fut2: IntoFuture<Item = S, Error = Err2> + 'static,
|
||||||
|
Req: 'static,
|
||||||
|
Resp: 'static,
|
||||||
|
Err1: 'static,
|
||||||
|
Err2: 'static,
|
||||||
|
{
|
||||||
|
type Request = Req;
|
||||||
|
type Response = Resp;
|
||||||
|
type Error = Err1;
|
||||||
|
type Service = FnStateService<S, F1, Req, Resp, Err1, Fut1>;
|
||||||
|
type InitError = Err2;
|
||||||
|
type Future = Box<Future<Item = Self::Service, Error = Self::InitError>>;
|
||||||
|
|
||||||
|
fn new_service(&self) -> Self::Future {
|
||||||
|
let f = self.f.clone();
|
||||||
|
Box::new(
|
||||||
|
(self.state)()
|
||||||
|
.into_future()
|
||||||
|
.and_then(move |state| Ok(FnStateService::new(state, f))),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S, F1, F2, Req, Resp, Err1, Err2, Fut1, Fut2>
|
||||||
|
IntoNewService<FnStateNewService<S, F1, F2, Req, Resp, Err1, Err2, Fut1, Fut2>> for (F1, F2)
|
||||||
|
where
|
||||||
|
S: 'static,
|
||||||
|
F1: Fn(&mut S, Req) -> Fut1 + Clone + 'static,
|
||||||
|
F2: Fn() -> Fut2,
|
||||||
|
Fut1: IntoFuture<Item = Resp, Error = Err1> + 'static,
|
||||||
|
Fut2: IntoFuture<Item = S, Error = Err2> + 'static,
|
||||||
|
Req: 'static,
|
||||||
|
Resp: 'static,
|
||||||
|
Err1: 'static,
|
||||||
|
Err2: 'static,
|
||||||
|
{
|
||||||
|
fn into_new_service(
|
||||||
|
self,
|
||||||
|
) -> FnStateNewService<S, F1, F2, Req, Resp, Err1, Err2, Fut1, Fut2> {
|
||||||
|
FnStateNewService::new(self.0, self.1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S, F1, F2, Req, Resp, Err1, Err2, Fut1, Fut2> Clone
|
||||||
|
for FnStateNewService<S, F1, F2, Req, Resp, Err1, Err2, Fut1, Fut2>
|
||||||
|
where
|
||||||
|
F1: Fn(&mut S, Req) -> Fut1 + Clone + 'static,
|
||||||
|
F2: Fn() -> Fut2 + Clone,
|
||||||
|
Fut1: IntoFuture<Item = Resp, Error = Err1>,
|
||||||
|
Fut2: IntoFuture<Item = S, Error = Err2>,
|
||||||
|
{
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Self::new(self.f.clone(), self.state.clone())
|
||||||
|
}
|
||||||
|
}
|
168
src/service/map_err.rs
Normal file
168
src/service/map_err.rs
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
use std::marker;
|
||||||
|
|
||||||
|
use futures::{Async, Future, Poll};
|
||||||
|
use tower_service::{NewService, Service};
|
||||||
|
|
||||||
|
/// `MapErr` service combinator
|
||||||
|
pub struct MapErr<A, F, E> {
|
||||||
|
a: A,
|
||||||
|
f: F,
|
||||||
|
e: marker::PhantomData<E>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A, F, E> MapErr<A, F, E>
|
||||||
|
where
|
||||||
|
A: Service,
|
||||||
|
F: Fn(A::Error) -> E,
|
||||||
|
{
|
||||||
|
/// Create new `MapErr` combinator
|
||||||
|
pub fn new(a: A, f: F) -> Self {
|
||||||
|
Self {
|
||||||
|
a,
|
||||||
|
f,
|
||||||
|
e: marker::PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A, F, E> Service for MapErr<A, F, E>
|
||||||
|
where
|
||||||
|
A: Service,
|
||||||
|
F: Fn(A::Error) -> E,
|
||||||
|
F: Clone,
|
||||||
|
{
|
||||||
|
type Request = A::Request;
|
||||||
|
type Response = A::Response;
|
||||||
|
type Error = E;
|
||||||
|
type Future = MapErrFuture<A, F, E>;
|
||||||
|
|
||||||
|
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||||
|
self.a.poll_ready().map_err(&self.f)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn call(&mut self, req: Self::Request) -> Self::Future {
|
||||||
|
MapErrFuture::new(self.a.call(req), self.f.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct MapErrFuture<A, F, E>
|
||||||
|
where
|
||||||
|
A: Service,
|
||||||
|
F: Fn(A::Error) -> E,
|
||||||
|
{
|
||||||
|
f: F,
|
||||||
|
fut: A::Future,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A, F, E> MapErrFuture<A, F, E>
|
||||||
|
where
|
||||||
|
A: Service,
|
||||||
|
F: Fn(A::Error) -> E,
|
||||||
|
{
|
||||||
|
fn new(fut: A::Future, f: F) -> Self {
|
||||||
|
MapErrFuture { f, fut }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A, F, E> Future for MapErrFuture<A, F, E>
|
||||||
|
where
|
||||||
|
A: Service,
|
||||||
|
F: Fn(A::Error) -> E,
|
||||||
|
{
|
||||||
|
type Item = A::Response;
|
||||||
|
type Error = E;
|
||||||
|
|
||||||
|
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||||
|
self.fut.poll().map_err(&self.f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `MapErrNewService` new service combinator
|
||||||
|
pub struct MapErrNewService<A, F, E> {
|
||||||
|
a: A,
|
||||||
|
f: F,
|
||||||
|
e: marker::PhantomData<E>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A, F, E> MapErrNewService<A, F, E>
|
||||||
|
where
|
||||||
|
A: NewService,
|
||||||
|
F: Fn(A::Error) -> E,
|
||||||
|
{
|
||||||
|
/// Create new `MapErr` new service instance
|
||||||
|
pub fn new(a: A, f: F) -> Self {
|
||||||
|
Self {
|
||||||
|
a,
|
||||||
|
f,
|
||||||
|
e: marker::PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A, F, E> Clone for MapErrNewService<A, F, E>
|
||||||
|
where
|
||||||
|
A: NewService + Clone,
|
||||||
|
F: Fn(A::Error) -> E + Clone,
|
||||||
|
{
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Self {
|
||||||
|
a: self.a.clone(),
|
||||||
|
f: self.f.clone(),
|
||||||
|
e: marker::PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A, F, E> NewService for MapErrNewService<A, F, E>
|
||||||
|
where
|
||||||
|
A: NewService + Clone,
|
||||||
|
F: Fn(A::Error) -> E + Clone,
|
||||||
|
{
|
||||||
|
type Request = A::Request;
|
||||||
|
type Response = A::Response;
|
||||||
|
type Error = E;
|
||||||
|
type Service = MapErr<A::Service, F, E>;
|
||||||
|
|
||||||
|
type InitError = A::InitError;
|
||||||
|
type Future = MapErrNewServiceFuture<A, F, E>;
|
||||||
|
|
||||||
|
fn new_service(&self) -> Self::Future {
|
||||||
|
MapErrNewServiceFuture::new(self.a.new_service(), self.f.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct MapErrNewServiceFuture<A, F, E>
|
||||||
|
where
|
||||||
|
A: NewService,
|
||||||
|
F: Fn(A::Error) -> E,
|
||||||
|
{
|
||||||
|
fut: A::Future,
|
||||||
|
f: F,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A, F, E> MapErrNewServiceFuture<A, F, E>
|
||||||
|
where
|
||||||
|
A: NewService,
|
||||||
|
F: Fn(A::Error) -> E,
|
||||||
|
{
|
||||||
|
fn new(fut: A::Future, f: F) -> Self {
|
||||||
|
MapErrNewServiceFuture { f, fut }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A, F, E> Future for MapErrNewServiceFuture<A, F, E>
|
||||||
|
where
|
||||||
|
A: NewService,
|
||||||
|
F: Fn(A::Error) -> E + Clone,
|
||||||
|
{
|
||||||
|
type Item = MapErr<A::Service, F, E>;
|
||||||
|
type Error = A::InitError;
|
||||||
|
|
||||||
|
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||||
|
if let Async::Ready(service) = self.fut.poll()? {
|
||||||
|
Ok(Async::Ready(MapErr::new(service, self.f.clone())))
|
||||||
|
} else {
|
||||||
|
Ok(Async::NotReady)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
90
src/service/map_init_err.rs
Normal file
90
src/service/map_init_err.rs
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
use std::marker;
|
||||||
|
|
||||||
|
use futures::{Future, Poll};
|
||||||
|
use tower_service::NewService;
|
||||||
|
|
||||||
|
/// `MapInitErr` service combinator
|
||||||
|
pub struct MapInitErr<A, F, E> {
|
||||||
|
a: A,
|
||||||
|
f: F,
|
||||||
|
e: marker::PhantomData<E>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A, F, E> MapInitErr<A, F, E>
|
||||||
|
where
|
||||||
|
A: NewService,
|
||||||
|
F: Fn(A::InitError) -> E,
|
||||||
|
{
|
||||||
|
/// Create new `MapInitErr` combinator
|
||||||
|
pub fn new(a: A, f: F) -> Self {
|
||||||
|
Self {
|
||||||
|
a,
|
||||||
|
f,
|
||||||
|
e: marker::PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A, F, E> Clone for MapInitErr<A, F, E>
|
||||||
|
where
|
||||||
|
A: NewService + Clone,
|
||||||
|
F: Fn(A::InitError) -> E + Clone,
|
||||||
|
{
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Self {
|
||||||
|
a: self.a.clone(),
|
||||||
|
f: self.f.clone(),
|
||||||
|
e: marker::PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A, F, E> NewService for MapInitErr<A, F, E>
|
||||||
|
where
|
||||||
|
A: NewService,
|
||||||
|
F: Fn(A::InitError) -> E + Clone,
|
||||||
|
{
|
||||||
|
type Request = A::Request;
|
||||||
|
type Response = A::Response;
|
||||||
|
type Error = A::Error;
|
||||||
|
type Service = A::Service;
|
||||||
|
|
||||||
|
type InitError = E;
|
||||||
|
type Future = MapInitErrFuture<A, F, E>;
|
||||||
|
|
||||||
|
fn new_service(&self) -> Self::Future {
|
||||||
|
MapInitErrFuture::new(self.a.new_service(), self.f.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct MapInitErrFuture<A, F, E>
|
||||||
|
where
|
||||||
|
A: NewService,
|
||||||
|
F: Fn(A::InitError) -> E,
|
||||||
|
{
|
||||||
|
f: F,
|
||||||
|
fut: A::Future,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A, F, E> MapInitErrFuture<A, F, E>
|
||||||
|
where
|
||||||
|
A: NewService,
|
||||||
|
F: Fn(A::InitError) -> E,
|
||||||
|
{
|
||||||
|
fn new(fut: A::Future, f: F) -> Self {
|
||||||
|
MapInitErrFuture { f, fut }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A, F, E> Future for MapInitErrFuture<A, F, E>
|
||||||
|
where
|
||||||
|
A: NewService,
|
||||||
|
F: Fn(A::InitError) -> E,
|
||||||
|
{
|
||||||
|
type Item = A::Service;
|
||||||
|
type Error = E;
|
||||||
|
|
||||||
|
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||||
|
self.fut.poll().map_err(&self.f)
|
||||||
|
}
|
||||||
|
}
|
93
src/service/mod.rs
Normal file
93
src/service/mod.rs
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
use futures::IntoFuture;
|
||||||
|
use tower_service::{NewService, Service};
|
||||||
|
|
||||||
|
mod and_then;
|
||||||
|
mod fn_service;
|
||||||
|
mod fn_state_service;
|
||||||
|
mod map_err;
|
||||||
|
mod map_init_err;
|
||||||
|
|
||||||
|
pub use self::and_then::{AndThen, AndThenNewService};
|
||||||
|
pub use self::fn_service::FnService;
|
||||||
|
pub use self::fn_state_service::FnStateService;
|
||||||
|
pub use self::map_err::{MapErr, MapErrNewService};
|
||||||
|
pub use self::map_init_err::MapInitErr;
|
||||||
|
|
||||||
|
pub trait NewServiceExt: NewService {
|
||||||
|
fn and_then<F, B>(self, new_service: F) -> AndThenNewService<Self, B>
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
F: IntoNewService<B>,
|
||||||
|
B: NewService<
|
||||||
|
Request = Self::Response,
|
||||||
|
Error = Self::Error,
|
||||||
|
InitError = Self::InitError,
|
||||||
|
>,
|
||||||
|
{
|
||||||
|
AndThenNewService::new(self, new_service)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn map_err<F, E>(self, f: F) -> MapErrNewService<Self, F, E>
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
F: Fn(Self::Error) -> E,
|
||||||
|
{
|
||||||
|
MapErrNewService::new(self, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn map_init_err<F, E>(self, f: F) -> MapInitErr<Self, F, E>
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
F: Fn(Self::InitError) -> E,
|
||||||
|
{
|
||||||
|
MapInitErr::new(self, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: NewService> NewServiceExt for T {}
|
||||||
|
|
||||||
|
/// Trait for types that can be converted to a Service
|
||||||
|
pub trait IntoService<T>
|
||||||
|
where
|
||||||
|
T: Service,
|
||||||
|
{
|
||||||
|
/// Create service
|
||||||
|
fn into(self) -> T;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Trait for types that can be converted to a Service
|
||||||
|
pub trait IntoNewService<T>
|
||||||
|
where
|
||||||
|
T: NewService,
|
||||||
|
{
|
||||||
|
/// Create service
|
||||||
|
fn into_new_service(self) -> T;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> IntoService<T> for T
|
||||||
|
where
|
||||||
|
T: Service,
|
||||||
|
{
|
||||||
|
fn into(self) -> T {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> IntoNewService<T> for T
|
||||||
|
where
|
||||||
|
T: NewService,
|
||||||
|
{
|
||||||
|
fn into_new_service(self) -> T {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<F, Req, Resp, Err, Fut> IntoService<FnService<F, Req, Resp, Err, Fut>> for F
|
||||||
|
where
|
||||||
|
F: Fn(Req) -> Fut + 'static,
|
||||||
|
Fut: IntoFuture<Item = Resp, Error = Err>,
|
||||||
|
{
|
||||||
|
fn into(self) -> FnService<F, Req, Resp, Err, Fut> {
|
||||||
|
FnService::new(self)
|
||||||
|
}
|
||||||
|
}
|
@ -2,7 +2,7 @@
|
|||||||
#[cfg(feature = "ssl")]
|
#[cfg(feature = "ssl")]
|
||||||
mod openssl;
|
mod openssl;
|
||||||
#[cfg(feature = "ssl")]
|
#[cfg(feature = "ssl")]
|
||||||
pub use self::openssl::OpensslService;
|
pub use self::openssl::{OpensslAcceptor, OpensslConnector};
|
||||||
|
|
||||||
// #[cfg(feature = "tls")]
|
// #[cfg(feature = "tls")]
|
||||||
// mod nativetls;
|
// mod nativetls;
|
||||||
|
@ -1,26 +1,25 @@
|
|||||||
use std::marker::PhantomData;
|
|
||||||
// use std::net::Shutdown;
|
|
||||||
use std::io;
|
use std::io;
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
use futures::{future, future::FutureResult, Async, Future, Poll};
|
use futures::{future, future::FutureResult, Async, Poll};
|
||||||
use openssl::ssl::{AlpnError, SslAcceptor, SslAcceptorBuilder};
|
use openssl::ssl::{AlpnError, Error, SslAcceptor, SslAcceptorBuilder, SslConnector};
|
||||||
use tokio_io::{AsyncRead, AsyncWrite};
|
use tokio_io::{AsyncRead, AsyncWrite};
|
||||||
use tokio_openssl::{AcceptAsync, SslAcceptorExt, SslStream};
|
use tokio_openssl::{AcceptAsync, ConnectAsync, SslAcceptorExt, SslConnectorExt, SslStream};
|
||||||
|
|
||||||
use {NewService, Service};
|
use {NewService, Service};
|
||||||
|
|
||||||
/// Support `SSL` connections via openssl package
|
/// Support `SSL` connections via openssl package
|
||||||
///
|
///
|
||||||
/// `alpn` feature enables `OpensslAcceptor` type
|
/// `ssl` feature enables `OpensslAcceptor` type
|
||||||
pub struct OpensslService<T> {
|
pub struct OpensslAcceptor<T> {
|
||||||
acceptor: SslAcceptor,
|
acceptor: SslAcceptor,
|
||||||
io: PhantomData<T>,
|
io: PhantomData<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> OpensslService<T> {
|
impl<T> OpensslAcceptor<T> {
|
||||||
/// Create default `OpensslService`
|
/// Create default `OpensslAcceptor`
|
||||||
pub fn new(builder: SslAcceptorBuilder) -> Self {
|
pub fn new(builder: SslAcceptorBuilder) -> Self {
|
||||||
OpensslService {
|
OpensslAcceptor {
|
||||||
acceptor: builder.build(),
|
acceptor: builder.build(),
|
||||||
io: PhantomData,
|
io: PhantomData,
|
||||||
}
|
}
|
||||||
@ -40,13 +39,13 @@ impl<T> OpensslService<T> {
|
|||||||
});
|
});
|
||||||
builder.set_alpn_protos(&protos[..])?;
|
builder.set_alpn_protos(&protos[..])?;
|
||||||
|
|
||||||
Ok(OpensslService {
|
Ok(OpensslAcceptor {
|
||||||
acceptor: builder.build(),
|
acceptor: builder.build(),
|
||||||
io: PhantomData,
|
io: PhantomData,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<T: AsyncRead + AsyncWrite> Clone for OpensslService<T> {
|
impl<T: AsyncRead + AsyncWrite> Clone for OpensslAcceptor<T> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
acceptor: self.acceptor.clone(),
|
acceptor: self.acceptor.clone(),
|
||||||
@ -55,69 +54,102 @@ impl<T: AsyncRead + AsyncWrite> Clone for OpensslService<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: AsyncRead + AsyncWrite> NewService for OpensslService<T> {
|
impl<T: AsyncRead + AsyncWrite> NewService for OpensslAcceptor<T> {
|
||||||
type Request = T;
|
type Request = T;
|
||||||
type Response = SslStream<T>;
|
type Response = SslStream<T>;
|
||||||
type Error = io::Error;
|
type Error = Error;
|
||||||
type Service = OpensslAcceptor<T>;
|
type Service = OpensslAcceptorService<T>;
|
||||||
type InitError = io::Error;
|
type InitError = io::Error;
|
||||||
type Future = FutureResult<Self::Service, io::Error>;
|
type Future = FutureResult<Self::Service, io::Error>;
|
||||||
|
|
||||||
fn new_service(&self) -> Self::Future {
|
fn new_service(&self) -> Self::Future {
|
||||||
future::ok(OpensslAcceptor {
|
future::ok(OpensslAcceptorService {
|
||||||
acceptor: self.acceptor.clone(),
|
acceptor: self.acceptor.clone(),
|
||||||
io: PhantomData,
|
io: PhantomData,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct OpensslAcceptor<T> {
|
pub struct OpensslAcceptorService<T> {
|
||||||
acceptor: SslAcceptor,
|
acceptor: SslAcceptor,
|
||||||
io: PhantomData<T>,
|
io: PhantomData<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: AsyncRead + AsyncWrite> Service for OpensslAcceptor<T> {
|
impl<T: AsyncRead + AsyncWrite> Service for OpensslAcceptorService<T> {
|
||||||
type Request = T;
|
type Request = T;
|
||||||
type Response = SslStream<T>;
|
type Response = SslStream<T>;
|
||||||
type Error = io::Error;
|
type Error = Error;
|
||||||
type Future = AcceptorFuture<T>;
|
type Future = AcceptAsync<T>;
|
||||||
|
|
||||||
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||||
Ok(Async::Ready(()))
|
Ok(Async::Ready(()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call(&mut self, req: Self::Request) -> Self::Future {
|
fn call(&mut self, req: Self::Request) -> Self::Future {
|
||||||
AcceptorFuture(SslAcceptorExt::accept_async(&self.acceptor, req))
|
SslAcceptorExt::accept_async(&self.acceptor, req)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct AcceptorFuture<T>(AcceptAsync<T>);
|
/// Openssl connector factory
|
||||||
|
pub struct OpensslConnector<T> {
|
||||||
|
connector: SslConnector,
|
||||||
|
io: PhantomData<T>,
|
||||||
|
}
|
||||||
|
|
||||||
impl<T: AsyncRead + AsyncWrite> Future for AcceptorFuture<T> {
|
impl<T> OpensslConnector<T> {
|
||||||
type Item = SslStream<T>;
|
pub fn new(connector: SslConnector) -> Self {
|
||||||
type Error = io::Error;
|
OpensslConnector {
|
||||||
|
connector,
|
||||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
io: PhantomData,
|
||||||
self.0
|
}
|
||||||
.poll()
|
|
||||||
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// impl<T: IoStream> IoStream for SslStream<T> {
|
impl<T> Clone for OpensslConnector<T> {
|
||||||
// #[inline]
|
fn clone(&self) -> Self {
|
||||||
// fn shutdown(&mut self, _how: Shutdown) -> io::Result<()> {
|
Self {
|
||||||
// let _ = self.get_mut().shutdown();
|
connector: self.connector.clone(),
|
||||||
// Ok(())
|
io: PhantomData,
|
||||||
// }
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// #[inline]
|
impl<T: AsyncRead + AsyncWrite> NewService for OpensslConnector<T> {
|
||||||
// fn set_nodelay(&mut self, nodelay: bool) -> io::Result<()> {
|
type Request = T;
|
||||||
// self.get_mut().get_mut().set_nodelay(nodelay)
|
type Response = SslStream<T>;
|
||||||
// }
|
type Error = Error;
|
||||||
|
type Service = OpensslConnectorService<T>;
|
||||||
|
type InitError = io::Error;
|
||||||
|
type Future = FutureResult<Self::Service, Self::InitError>;
|
||||||
|
|
||||||
// #[inline]
|
fn new_service(&self) -> Self::Future {
|
||||||
// fn set_linger(&mut self, dur: Option<time::Duration>) -> io::Result<()> {
|
future::ok(OpensslConnectorService {
|
||||||
// self.get_mut().get_mut().set_linger(dur)
|
connector: self.connector.clone(),
|
||||||
// }
|
io: PhantomData,
|
||||||
// }
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait OpensslDomain {
|
||||||
|
fn domain(&self) -> &str;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct OpensslConnectorService<T> {
|
||||||
|
connector: SslConnector,
|
||||||
|
io: PhantomData<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: AsyncRead + AsyncWrite> Service for OpensslConnectorService<T> {
|
||||||
|
type Request = T;
|
||||||
|
type Response = SslStream<T>;
|
||||||
|
type Error = Error;
|
||||||
|
type Future = ConnectAsync<T>;
|
||||||
|
|
||||||
|
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||||
|
Ok(Async::Ready(()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn call(&mut self, req: Self::Request) -> Self::Future {
|
||||||
|
SslConnectorExt::connect_async(&self.connector, "", req)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user