use std::marker::PhantomData; use futures::{Async, Future, IntoFuture, Poll}; use {IntoNewService, NewService, Service}; /// `Apply` service combinator pub struct Apply { service: T, f: F, r: PhantomData R>, } impl Apply where T: Service, T::Error: Into<::Error>, F: Fn(Req, &mut T) -> R, R: IntoFuture, { /// Create new `Apply` combinator pub fn new(f: F, service: T) -> Self { Self { service, f, r: PhantomData, } } } impl Service for Apply where T: Service, T::Error: Into<::Error>, F: Fn(Req, &mut T) -> R, R: IntoFuture, { type Request = Req; type Response = ::Item; type Error = ::Error; type Future = R::Future; fn poll_ready(&mut self) -> Poll<(), Self::Error> { self.service.poll_ready().map_err(|e| e.into()) } fn call(&mut self, req: Self::Request) -> Self::Future { (self.f)(req, &mut self.service).into_future() } } /// `ApplyNewService` new service combinator pub struct ApplyNewService { service: T, f: F, r: PhantomData R>, } impl ApplyNewService where T: NewService, F: Fn(Req, &mut T::Service) -> R, R: IntoFuture, { /// Create new `ApplyNewService` new service instance pub fn new>(f: F, service: F1) -> Self { Self { f, service: service.into_new_service(), r: PhantomData, } } } impl Clone for ApplyNewService where T: NewService + Clone, F: Fn(Req, &mut T::Service) -> R + Clone, R: IntoFuture, { fn clone(&self) -> Self { Self { service: self.service.clone(), f: self.f.clone(), r: PhantomData, } } } impl NewService for ApplyNewService where T: NewService, T::Error: Into<::Error>, F: Fn(Req, &mut T::Service) -> R + Clone, R: IntoFuture, { type Request = Req; type Response = ::Item; type Error = ::Error; type Service = Apply; type InitError = T::InitError; type Future = ApplyNewServiceFuture; fn new_service(&self) -> Self::Future { ApplyNewServiceFuture::new(self.service.new_service(), self.f.clone()) } } pub struct ApplyNewServiceFuture where T: NewService, F: Fn(Req, &mut T::Service) -> R, R: IntoFuture, { fut: T::Future, f: Option, r: PhantomData R>, } impl ApplyNewServiceFuture where T: NewService, F: Fn(Req, &mut T::Service) -> R, R: IntoFuture, { fn new(fut: T::Future, f: F) -> Self { ApplyNewServiceFuture { f: Some(f), fut, r: PhantomData, } } } impl Future for ApplyNewServiceFuture where T: NewService, T::Error: Into<::Error>, F: Fn(Req, &mut T::Service) -> R, R: IntoFuture, { type Item = Apply; type Error = T::InitError; fn poll(&mut self) -> Poll { if let Async::Ready(service) = self.fut.poll()? { Ok(Async::Ready(Apply::new(self.f.take().unwrap(), service))) } else { Ok(Async::NotReady) } } }