#![allow(unused_imports, unused_variables, dead_code)] use std::future::Future; use std::pin::Pin; use std::task::{Context, Poll}; use futures::future::{err, ok, Either, Ready}; use futures::future::{FutureExt, LocalBoxFuture}; use crate::{Service, ServiceFactory}; pub type BoxedService = Box< dyn Service< Request = Req, Response = Res, Error = Err, Future = BoxedServiceResponse, >, >; pub type BoxedServiceResponse = Either>, LocalBoxFuture<'static, Result>>; pub struct BoxedNewService(Inner); /// Create boxed new service pub fn factory( factory: T, ) -> BoxedNewService where T: ServiceFactory + 'static, T::Request: 'static, T::Response: 'static, T::Service: 'static, T::Future: 'static, T::Error: 'static, T::InitError: 'static, { BoxedNewService(Box::new(FactoryWrapper { factory, _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< dyn ServiceFactory< Config = C, Request = Req, Response = Res, Error = Err, InitError = InitErr, Service = BoxedService, Future = LocalBoxFuture<'static, Result, InitErr>>, >, >; impl ServiceFactory 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 = LocalBoxFuture<'static, Result>; fn new_service(&self, cfg: &C) -> Self::Future { self.0.new_service(cfg) } } struct FactoryWrapper { factory: T, _t: std::marker::PhantomData, } impl ServiceFactory for FactoryWrapper where Req: 'static, Res: 'static, Err: 'static, InitErr: 'static, T: ServiceFactory< Config = C, Request = Req, Response = Res, Error = Err, InitError = InitErr, >, 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 = LocalBoxFuture<'static, Result>; fn new_service(&self, cfg: &C) -> Self::Future { /* TODO: Figure out what the hell is hapenning here Box::new( self.service .new_service(cfg) .into_future() .map(ServiceWrapper::boxed), ) */ unimplemented!() } } 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< Ready>, LocalBoxFuture<'static, Result>, >; fn poll_ready(&mut self, ctx: &mut Context<'_>) -> Poll> { self.0.poll_ready(ctx) } fn call(&mut self, req: Self::Request) -> Self::Future { unimplemented!() } /* 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)), } } */ }