use futures::future::{err, ok, Either, FutureResult}; use futures::{Async, Future, IntoFuture, Poll}; use crate::{NewService, Service}; pub type BoxedService = Box< Service< Request = Req, Response = Res, Error = Err, Future = BoxedServiceResponse, >, >; pub type BoxedServiceResponse = Either, Box>>; pub struct BoxedNewService(Inner); /// Create boxed new service pub fn new_service( service: T, ) -> BoxedNewService where T: NewService + 'static, T::Request: 'static, T::Response: 'static, T::Service: 'static, T::Future: 'static, T::Error: 'static, T::InitError: 'static, { BoxedNewService(Box::new(NewServiceWrapper { service, _t: std::marker::PhantomData, })) } /// Create boxed service pub fn service(service: T) -> BoxedService where T: Service + 'static, T::Future: 'static, { Box::new(ServiceWrapper(service)) } type Inner = Box< NewService< Config = C, Request = Req, Response = Res, Error = Err, InitError = InitErr, Service = BoxedService, Future = Box, Error = InitErr>>, >, >; impl NewService for BoxedNewService where Req: 'static, Res: 'static, Err: 'static, InitErr: 'static, { type Request = Req; type Response = Res; type Error = Err; type InitError = InitErr; type Config = C; type Service = BoxedService; type Future = Box>; fn new_service(&self, cfg: &C) -> Self::Future { self.0.new_service(cfg) } } struct NewServiceWrapper { service: T, _t: std::marker::PhantomData, } impl NewService for NewServiceWrapper where Req: 'static, Res: 'static, Err: 'static, InitErr: 'static, T: NewService, T::Future: 'static, T::Service: 'static, ::Future: 'static, { type Request = Req; type Response = Res; type Error = Err; type InitError = InitErr; type Config = C; type Service = BoxedService; type Future = Box>; fn new_service(&self, cfg: &C) -> Self::Future { Box::new( self.service .new_service(cfg) .into_future() .map(ServiceWrapper::boxed), ) } } struct ServiceWrapper(T); impl ServiceWrapper where T: Service + 'static, T::Future: 'static, { fn boxed(service: T) -> BoxedService { Box::new(ServiceWrapper(service)) } } impl Service for ServiceWrapper where T: Service, T::Future: 'static, { type Request = Req; type Response = Res; type Error = Err; type Future = Either< FutureResult, Box>, >; fn poll_ready(&mut self) -> Poll<(), Self::Error> { self.0.poll_ready() } fn call(&mut self, req: Self::Request) -> Self::Future { let mut fut = self.0.call(req); match fut.poll() { Ok(Async::Ready(res)) => Either::A(ok(res)), Err(e) => Either::A(err(e)), Ok(Async::NotReady) => Either::B(Box::new(fut)), } } }