use std::marker::PhantomData;
use futures::{Async, Future, Poll};
use super::Service;
pub trait Transform<Service> {
type Request;
type Response;
type Error;
type Future: Future<Item = Self::Response, Error = Self::Error>;
fn poll_ready(&mut self) -> Poll<(), Self::Error>;
fn call(&mut self, request: Self::Request, service: &mut Service) -> Self::Future;
fn map_err<F, E>(self, f: F) -> TransformMapErr<Self, Service, F, E>
where
Self: Sized,
F: Fn(Self::Error) -> E,
{
TransformMapErr::new(self, f)
}
}
pub trait NewTransform<Service> {
type Request;
type Response;
type Error;
type Transform: Transform<
Service,
Request = Self::Request,
Response = Self::Response,
Error = Self::Error,
>;
type InitError;
type Future: Future<Item = Self::Transform, Error = Self::InitError>;
fn new_transform(&self) -> Self::Future;
fn map_err<F, E>(self, f: F) -> TransformMapErrNewTransform<Self, Service, F, E>
where
Self: Sized,
F: Fn(Self::Error) -> E,
{
TransformMapErrNewTransform::new(self, f)
}
}
impl<'a, T, S> Transform<S> for &'a mut T
where
T: Transform<S> + 'a,
S: Service<Error = T::Error>,
{
type Request = T::Request;
type Response = T::Response;
type Error = T::Error;
type Future = T::Future;
fn poll_ready(&mut self) -> Poll<(), T::Error> {
(**self).poll_ready()
}
fn call(&mut self, request: Self::Request, service: &mut S) -> T::Future {
(**self).call(request, service)
}
}
impl<T, S> Transform<S> for Box<T>
where
T: Transform<S> + ?Sized,
S: Service<Error = T::Error>,
{
type Request = T::Request;
type Response = T::Response;
type Error = T::Error;
type Future = T::Future;
fn poll_ready(&mut self) -> Poll<(), S::Error> {
(**self).poll_ready()
}
fn call(&mut self, request: Self::Request, service: &mut S) -> T::Future {
(**self).call(request, service)
}
}
pub trait IntoTransform<T, S>
where
T: Transform<S>,
{
fn into_transform(self) -> T;
}
pub trait IntoNewTransform<T, S>
where
T: NewTransform<S>,
{
fn into_new_transform(self) -> T;
}
impl<T, S> IntoTransform<T, S> for T
where
T: Transform<S>,
{
fn into_transform(self) -> T {
self
}
}
impl<T, S> IntoNewTransform<T, S> for T
where
T: NewTransform<S>,
{
fn into_new_transform(self) -> T {
self
}
}
pub struct TransformMapErr<T, S, F, E> {
transform: T,
f: F,
_t: PhantomData<(S, E)>,
}
impl<T, S, F, E> TransformMapErr<T, S, F, E> {
pub fn new(transform: T, f: F) -> Self
where
T: Transform<S>,
F: Fn(T::Error) -> E,
{
Self {
transform,
f,
_t: PhantomData,
}
}
}
impl<T, S, F, E> Clone for TransformMapErr<T, S, F, E>
where
T: Clone,
F: Clone,
{
fn clone(&self) -> Self {
TransformMapErr {
transform: self.transform.clone(),
f: self.f.clone(),
_t: PhantomData,
}
}
}
impl<T, S, F, E> Transform<S> for TransformMapErr<T, S, F, E>
where
T: Transform<S>,
F: Fn(T::Error) -> E + Clone,
{
type Request = T::Request;
type Response = T::Response;
type Error = E;
type Future = TransformMapErrFuture<T, S, F, E>;
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
self.transform.poll_ready().map_err(&self.f)
}
fn call(&mut self, req: T::Request, service: &mut S) -> Self::Future {
TransformMapErrFuture::new(self.transform.call(req, service), self.f.clone())
}
}
pub struct TransformMapErrFuture<T, S, F, E>
where
T: Transform<S>,
F: Fn(T::Error) -> E,
{
f: F,
fut: T::Future,
}
impl<T, S, F, E> TransformMapErrFuture<T, S, F, E>
where
T: Transform<S>,
F: Fn(T::Error) -> E,
{
fn new(fut: T::Future, f: F) -> Self {
TransformMapErrFuture { f, fut }
}
}
impl<T, S, F, E> Future for TransformMapErrFuture<T, S, F, E>
where
T: Transform<S>,
F: Fn(T::Error) -> E,
{
type Item = T::Response;
type Error = E;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
self.fut.poll().map_err(&self.f)
}
}
pub struct TransformMapErrNewTransform<T, S, F, E> {
t: T,
f: F,
e: PhantomData<(S, E)>,
}
impl<T, S, F, E> TransformMapErrNewTransform<T, S, F, E> {
pub fn new(t: T, f: F) -> Self
where
T: NewTransform<S>,
F: Fn(T::Error) -> E,
{
Self {
t,
f,
e: PhantomData,
}
}
}
impl<T, S, F, E> Clone for TransformMapErrNewTransform<T, S, F, E>
where
T: Clone,
F: Clone,
{
fn clone(&self) -> Self {
Self {
t: self.t.clone(),
f: self.f.clone(),
e: PhantomData,
}
}
}
impl<T, S, F, E> NewTransform<S> for TransformMapErrNewTransform<T, S, F, E>
where
T: NewTransform<S>,
F: Fn(T::Error) -> E + Clone,
{
type Request = T::Request;
type Response = T::Response;
type Error = E;
type Transform = TransformMapErr<T::Transform, S, F, E>;
type InitError = T::InitError;
type Future = TransformMapErrNewTransformFuture<T, S, F, E>;
fn new_transform(&self) -> Self::Future {
TransformMapErrNewTransformFuture::new(self.t.new_transform(), self.f.clone())
}
}
pub struct TransformMapErrNewTransformFuture<T, S, F, E>
where
T: NewTransform<S>,
F: Fn(T::Error) -> E,
{
fut: T::Future,
f: F,
}
impl<T, S, F, E> TransformMapErrNewTransformFuture<T, S, F, E>
where
T: NewTransform<S>,
F: Fn(T::Error) -> E,
{
fn new(fut: T::Future, f: F) -> Self {
TransformMapErrNewTransformFuture { f, fut }
}
}
impl<T, S, F, E> Future for TransformMapErrNewTransformFuture<T, S, F, E>
where
T: NewTransform<S>,
F: Fn(T::Error) -> E + Clone,
{
type Item = TransformMapErr<T::Transform, S, F, E>;
type Error = T::InitError;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
if let Async::Ready(tr) = self.fut.poll()? {
Ok(Async::Ready(TransformMapErr::new(tr, self.f.clone())))
} else {
Ok(Async::NotReady)
}
}
}