use futures_util::future::BoxFuture; use std::future::Future; use std::task::{Context, Poll}; use tower::ServiceExt; use tower_service::Service; /// A boxed Service that implements Clone /// /// Could probably upstream this to tower pub(crate) struct CloneBoxService { inner: Box< dyn CloneService>> + Send, >, } impl CloneBoxService { pub(crate) fn new(inner: S) -> Self where S: Service + Clone + Send + 'static, S::Future: Send + 'static, { let inner = Box::new(inner.map_future(|f| Box::pin(f) as _)); Self { inner } } } impl Clone for CloneBoxService { fn clone(&self) -> Self { Self { inner: dyn_clone::clone_box(&*self.inner), } } } impl Service for CloneBoxService { type Response = U; type Error = E; type Future = BoxFuture<'static, Result>; fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { CloneService::poll_ready(&mut *self.inner, cx) } fn call(&mut self, req: T) -> Self::Future { CloneService::call(&mut *self.inner, req) } } trait CloneService: dyn_clone::DynClone { type Response; type Error; type Future: Future>; fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll>; fn call(&mut self, req: R) -> Self::Future; } impl CloneService for T where T: Service + Clone, { type Response = T::Response; type Error = T::Error; type Future = T::Future; fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { Service::poll_ready(self, cx) } fn call(&mut self, req: R) -> Self::Future { Service::call(self, req) } }