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