1 use super::ServiceExt;
2 use futures_util::future::BoxFuture;
3 use std::{
4     fmt,
5     task::{Context, Poll},
6 };
7 use tower_layer::{layer_fn, LayerFn};
8 use tower_service::Service;
9 
10 /// A [`Clone`] + [`Send`] boxed [`Service`].
11 ///
12 /// [`BoxCloneService`] turns a service into a trait object, allowing the
13 /// response future type to be dynamic, and allowing the service to be cloned.
14 ///
15 /// This is similar to [`BoxService`](super::BoxService) except the resulting
16 /// service implements [`Clone`].
17 ///
18 /// # Example
19 ///
20 /// ```
21 /// use tower::{Service, ServiceBuilder, BoxError, util::BoxCloneService};
22 /// use std::time::Duration;
23 /// #
24 /// # struct Request;
25 /// # struct Response;
26 /// # impl Response {
27 /// #     fn new() -> Self { Self }
28 /// # }
29 ///
30 /// // This service has a complex type that is hard to name
31 /// let service = ServiceBuilder::new()
32 ///     .map_request(|req| {
33 ///         println!("received request");
34 ///         req
35 ///     })
36 ///     .map_response(|res| {
37 ///         println!("response produced");
38 ///         res
39 ///     })
40 ///     .load_shed()
41 ///     .concurrency_limit(64)
42 ///     .timeout(Duration::from_secs(10))
43 ///     .service_fn(|req: Request| async {
44 ///         Ok::<_, BoxError>(Response::new())
45 ///     });
46 /// # let service = assert_service(service);
47 ///
48 /// // `BoxCloneService` will erase the type so it's nameable
49 /// let service: BoxCloneService<Request, Response, BoxError> = BoxCloneService::new(service);
50 /// # let service = assert_service(service);
51 ///
52 /// // And we can still clone the service
53 /// let cloned_service = service.clone();
54 /// #
55 /// # fn assert_service<S, R>(svc: S) -> S
56 /// # where S: Service<R> { svc }
57 /// ```
58 pub struct BoxCloneService<T, U, E>(
59     Box<
60         dyn CloneService<T, Response = U, Error = E, Future = BoxFuture<'static, Result<U, E>>>
61             + Send,
62     >,
63 );
64 
65 impl<T, U, E> BoxCloneService<T, U, E> {
66     /// Create a new `BoxCloneService`.
new<S>(inner: S) -> Self where S: Service<T, Response = U, Error = E> + Clone + Send + 'static, S::Future: Send + 'static,67     pub fn new<S>(inner: S) -> Self
68     where
69         S: Service<T, Response = U, Error = E> + Clone + Send + 'static,
70         S::Future: Send + 'static,
71     {
72         let inner = inner.map_future(|f| Box::pin(f) as _);
73         BoxCloneService(Box::new(inner))
74     }
75 
76     /// Returns a [`Layer`] for wrapping a [`Service`] in a [`BoxCloneService`]
77     /// middleware.
78     ///
79     /// [`Layer`]: crate::Layer
layer<S>() -> LayerFn<fn(S) -> Self> where S: Service<T, Response = U, Error = E> + Clone + Send + 'static, S::Future: Send + 'static,80     pub fn layer<S>() -> LayerFn<fn(S) -> Self>
81     where
82         S: Service<T, Response = U, Error = E> + Clone + Send + 'static,
83         S::Future: Send + 'static,
84     {
85         layer_fn(Self::new)
86     }
87 }
88 
89 impl<T, U, E> Service<T> for BoxCloneService<T, U, E> {
90     type Response = U;
91     type Error = E;
92     type Future = BoxFuture<'static, Result<U, E>>;
93 
94     #[inline]
poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), E>>95     fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), E>> {
96         self.0.poll_ready(cx)
97     }
98 
99     #[inline]
call(&mut self, request: T) -> Self::Future100     fn call(&mut self, request: T) -> Self::Future {
101         self.0.call(request)
102     }
103 }
104 
105 impl<T, U, E> Clone for BoxCloneService<T, U, E> {
clone(&self) -> Self106     fn clone(&self) -> Self {
107         Self(self.0.clone_box())
108     }
109 }
110 
111 trait CloneService<R>: Service<R> {
clone_box( &self, ) -> Box< dyn CloneService<R, Response = Self::Response, Error = Self::Error, Future = Self::Future> + Send, >112     fn clone_box(
113         &self,
114     ) -> Box<
115         dyn CloneService<R, Response = Self::Response, Error = Self::Error, Future = Self::Future>
116             + Send,
117     >;
118 }
119 
120 impl<R, T> CloneService<R> for T
121 where
122     T: Service<R> + Send + Clone + 'static,
123 {
clone_box( &self, ) -> Box<dyn CloneService<R, Response = T::Response, Error = T::Error, Future = T::Future> + Send>124     fn clone_box(
125         &self,
126     ) -> Box<dyn CloneService<R, Response = T::Response, Error = T::Error, Future = T::Future> + Send>
127     {
128         Box::new(self.clone())
129     }
130 }
131 
132 impl<T, U, E> fmt::Debug for BoxCloneService<T, U, E> {
fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result133     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
134         fmt.debug_struct("BoxCloneService").finish()
135     }
136 }
137