mirror of
https://github.com/actix/actix-web.git
synced 2024-12-30 12:00:38 +00:00
split service mod
This commit is contained in:
parent
0eae4d84b1
commit
89b8da724b
11 changed files with 917 additions and 847 deletions
|
@ -110,19 +110,18 @@ where
|
|||
Fut: IntoFuture<Item = S, Error = Err>,
|
||||
{
|
||||
fn new(f: F) -> Self {
|
||||
Fn2NewConfigurableService{
|
||||
Fn2NewConfigurableService {
|
||||
f,
|
||||
err: marker::PhantomData,
|
||||
cfg: marker::PhantomData,
|
||||
fut: marker::PhantomData,
|
||||
s: marker::PhantomData
|
||||
s: marker::PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<F, S, Err, Fut, Cfg>
|
||||
IntoNewConfigurableService<Fn2NewConfigurableService<F, S, Err, Fut, Cfg>>
|
||||
for F
|
||||
IntoNewConfigurableService<Fn2NewConfigurableService<F, S, Err, Fut, Cfg>> for F
|
||||
where
|
||||
S: Service,
|
||||
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
|
||||
S: Service,
|
||||
F: Fn(Cfg) -> Fut,
|
||||
|
|
|
@ -60,7 +60,7 @@ pub mod service;
|
|||
pub mod ssl;
|
||||
mod worker;
|
||||
|
||||
pub use configurable::{NewConfigurableService, IntoNewConfigurableService};
|
||||
pub use configurable::{IntoNewConfigurableService, NewConfigurableService};
|
||||
pub use connector::{Connector, ConnectorError};
|
||||
pub use server::Server;
|
||||
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")]
|
||||
mod openssl;
|
||||
#[cfg(feature = "ssl")]
|
||||
pub use self::openssl::OpensslService;
|
||||
pub use self::openssl::{OpensslAcceptor, OpensslConnector};
|
||||
|
||||
// #[cfg(feature = "tls")]
|
||||
// mod nativetls;
|
||||
|
|
|
@ -1,26 +1,25 @@
|
|||
use std::marker::PhantomData;
|
||||
// use std::net::Shutdown;
|
||||
use std::io;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use futures::{future, future::FutureResult, Async, Future, Poll};
|
||||
use openssl::ssl::{AlpnError, SslAcceptor, SslAcceptorBuilder};
|
||||
use futures::{future, future::FutureResult, Async, Poll};
|
||||
use openssl::ssl::{AlpnError, Error, SslAcceptor, SslAcceptorBuilder, SslConnector};
|
||||
use tokio_io::{AsyncRead, AsyncWrite};
|
||||
use tokio_openssl::{AcceptAsync, SslAcceptorExt, SslStream};
|
||||
use tokio_openssl::{AcceptAsync, ConnectAsync, SslAcceptorExt, SslConnectorExt, SslStream};
|
||||
|
||||
use {NewService, Service};
|
||||
|
||||
/// Support `SSL` connections via openssl package
|
||||
///
|
||||
/// `alpn` feature enables `OpensslAcceptor` type
|
||||
pub struct OpensslService<T> {
|
||||
/// `ssl` feature enables `OpensslAcceptor` type
|
||||
pub struct OpensslAcceptor<T> {
|
||||
acceptor: SslAcceptor,
|
||||
io: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T> OpensslService<T> {
|
||||
/// Create default `OpensslService`
|
||||
impl<T> OpensslAcceptor<T> {
|
||||
/// Create default `OpensslAcceptor`
|
||||
pub fn new(builder: SslAcceptorBuilder) -> Self {
|
||||
OpensslService {
|
||||
OpensslAcceptor {
|
||||
acceptor: builder.build(),
|
||||
io: PhantomData,
|
||||
}
|
||||
|
@ -40,13 +39,13 @@ impl<T> OpensslService<T> {
|
|||
});
|
||||
builder.set_alpn_protos(&protos[..])?;
|
||||
|
||||
Ok(OpensslService {
|
||||
Ok(OpensslAcceptor {
|
||||
acceptor: builder.build(),
|
||||
io: PhantomData,
|
||||
})
|
||||
}
|
||||
}
|
||||
impl<T: AsyncRead + AsyncWrite> Clone for OpensslService<T> {
|
||||
impl<T: AsyncRead + AsyncWrite> Clone for OpensslAcceptor<T> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
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 Response = SslStream<T>;
|
||||
type Error = io::Error;
|
||||
type Service = OpensslAcceptor<T>;
|
||||
type Error = Error;
|
||||
type Service = OpensslAcceptorService<T>;
|
||||
type InitError = io::Error;
|
||||
type Future = FutureResult<Self::Service, io::Error>;
|
||||
|
||||
fn new_service(&self) -> Self::Future {
|
||||
future::ok(OpensslAcceptor {
|
||||
future::ok(OpensslAcceptorService {
|
||||
acceptor: self.acceptor.clone(),
|
||||
io: PhantomData,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub struct OpensslAcceptor<T> {
|
||||
pub struct OpensslAcceptorService<T> {
|
||||
acceptor: SslAcceptor,
|
||||
io: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T: AsyncRead + AsyncWrite> Service for OpensslAcceptor<T> {
|
||||
impl<T: AsyncRead + AsyncWrite> Service for OpensslAcceptorService<T> {
|
||||
type Request = T;
|
||||
type Response = SslStream<T>;
|
||||
type Error = io::Error;
|
||||
type Future = AcceptorFuture<T>;
|
||||
type Error = Error;
|
||||
type Future = AcceptAsync<T>;
|
||||
|
||||
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
|
||||
Ok(Async::Ready(()))
|
||||
}
|
||||
|
||||
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> {
|
||||
type Item = SslStream<T>;
|
||||
type Error = io::Error;
|
||||
|
||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||
self.0
|
||||
.poll()
|
||||
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))
|
||||
impl<T> OpensslConnector<T> {
|
||||
pub fn new(connector: SslConnector) -> Self {
|
||||
OpensslConnector {
|
||||
connector,
|
||||
io: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// impl<T: IoStream> IoStream for SslStream<T> {
|
||||
// #[inline]
|
||||
// fn shutdown(&mut self, _how: Shutdown) -> io::Result<()> {
|
||||
// let _ = self.get_mut().shutdown();
|
||||
// Ok(())
|
||||
// }
|
||||
impl<T> Clone for OpensslConnector<T> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
connector: self.connector.clone(),
|
||||
io: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// #[inline]
|
||||
// fn set_nodelay(&mut self, nodelay: bool) -> io::Result<()> {
|
||||
// self.get_mut().get_mut().set_nodelay(nodelay)
|
||||
// }
|
||||
impl<T: AsyncRead + AsyncWrite> NewService for OpensslConnector<T> {
|
||||
type Request = T;
|
||||
type Response = SslStream<T>;
|
||||
type Error = Error;
|
||||
type Service = OpensslConnectorService<T>;
|
||||
type InitError = io::Error;
|
||||
type Future = FutureResult<Self::Service, Self::InitError>;
|
||||
|
||||
// #[inline]
|
||||
// fn set_linger(&mut self, dur: Option<time::Duration>) -> io::Result<()> {
|
||||
// self.get_mut().get_mut().set_linger(dur)
|
||||
// }
|
||||
// }
|
||||
fn new_service(&self) -> Self::Future {
|
||||
future::ok(OpensslConnectorService {
|
||||
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 a new issue