tower/util/
boxed_clone_sync.rs1use super::ServiceExt;
2use futures_util::future::BoxFuture;
3use std::{
4 fmt,
5 task::{Context, Poll},
6};
7use tower_layer::{layer_fn, LayerFn};
8use tower_service::Service;
9
10pub struct BoxCloneSyncService<T, U, E>(
19 Box<
20 dyn CloneService<T, Response = U, Error = E, Future = BoxFuture<'static, Result<U, E>>>
21 + Send
22 + Sync,
23 >,
24);
25
26impl<T, U, E> BoxCloneSyncService<T, U, E> {
27 pub fn new<S>(inner: S) -> Self
29 where
30 S: Service<T, Response = U, Error = E> + Clone + Send + Sync + 'static,
31 S::Future: Send + 'static,
32 {
33 let inner = inner.map_future(|f| Box::pin(f) as _);
34 BoxCloneSyncService(Box::new(inner))
35 }
36
37 pub fn layer<S>() -> LayerFn<fn(S) -> Self>
42 where
43 S: Service<T, Response = U, Error = E> + Clone + Send + Sync + 'static,
44 S::Future: Send + 'static,
45 {
46 layer_fn(Self::new)
47 }
48}
49
50impl<T, U, E> Service<T> for BoxCloneSyncService<T, U, E> {
51 type Response = U;
52 type Error = E;
53 type Future = BoxFuture<'static, Result<U, E>>;
54
55 #[inline]
56 fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), E>> {
57 self.0.poll_ready(cx)
58 }
59
60 #[inline]
61 fn call(&mut self, request: T) -> Self::Future {
62 self.0.call(request)
63 }
64}
65
66impl<T, U, E> Clone for BoxCloneSyncService<T, U, E> {
67 fn clone(&self) -> Self {
68 Self(self.0.clone_box())
69 }
70}
71
72trait CloneService<R>: Service<R> {
73 fn clone_box(
74 &self,
75 ) -> Box<
76 dyn CloneService<R, Response = Self::Response, Error = Self::Error, Future = Self::Future>
77 + Send
78 + Sync,
79 >;
80}
81
82impl<R, T> CloneService<R> for T
83where
84 T: Service<R> + Send + Sync + Clone + 'static,
85{
86 fn clone_box(
87 &self,
88 ) -> Box<
89 dyn CloneService<R, Response = T::Response, Error = T::Error, Future = T::Future>
90 + Send
91 + Sync,
92 > {
93 Box::new(self.clone())
94 }
95}
96
97impl<T, U, E> fmt::Debug for BoxCloneSyncService<T, U, E> {
98 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
99 fmt.debug_struct("BoxCloneSyncService").finish()
100 }
101}