use std::task::{Context, Poll}; use actix_http::Error; use actix_service::{Service, ServiceFactory}; use futures::future::{FutureExt, LocalBoxFuture}; pub(crate) type BoxedHttpService = Box< dyn Service< Request = Req, Response = (), Error = Error, Future = LocalBoxFuture<'static, Result<(), Error>>, >, >; pub(crate) type BoxedHttpNewService = Box< dyn ServiceFactory< Config = (), Request = Req, Response = (), Error = Error, InitError = (), Service = BoxedHttpService, Future = LocalBoxFuture<'static, Result, ()>>, >, >; pub(crate) struct HttpNewService(T); impl HttpNewService where T: ServiceFactory, T::Response: 'static, T::Future: 'static, T::Service: Service>> + 'static, ::Future: 'static, { pub fn new(service: T) -> Self { HttpNewService(service) } } impl ServiceFactory for HttpNewService where T: ServiceFactory, T::Request: 'static, T::Future: 'static, T::Service: Service>> + 'static, ::Future: 'static, { type Config = (); type Request = T::Request; type Response = (); type Error = Error; type InitError = (); type Service = BoxedHttpService; type Future = LocalBoxFuture<'static, Result>; fn new_service(&self, _: &()) -> Self::Future { let fut = self.0.new_service(&()); async move { fut.await.map_err(|_| ()).map(|service| { let service: BoxedHttpService<_> = Box::new(HttpServiceWrapper { service }); service }) } .boxed_local() } } struct HttpServiceWrapper { service: T, } impl Service for HttpServiceWrapper where T: Service< Response = (), Future = LocalBoxFuture<'static, Result<(), Error>>, Error = Error, >, T::Request: 'static, { type Request = T::Request; type Response = (); type Error = Error; type Future = LocalBoxFuture<'static, Result<(), Error>>; fn poll_ready(&mut self, cx: &mut Context) -> Poll> { self.service.poll_ready(cx) } fn call(&mut self, req: Self::Request) -> Self::Future { self.service.call(req) } }