tower/util/boxed_clone.rs
1use 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
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/// ```
58pub 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
65impl<T, U, E> BoxCloneService<T, U, E> {
66 /// Create a new `BoxCloneService`.
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
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
89impl<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]
95 fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), E>> {
96 self.0.poll_ready(cx)
97 }
98
99 #[inline]
100 fn call(&mut self, request: T) -> Self::Future {
101 self.0.call(request)
102 }
103}
104
105impl<T, U, E> Clone for BoxCloneService<T, U, E> {
106 fn clone(&self) -> Self {
107 Self(self.0.clone_box())
108 }
109}
110
111trait CloneService<R>: Service<R> {
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
120impl<R, T> CloneService<R> for T
121where
122 T: Service<R> + Send + Clone + 'static,
123{
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
132impl<T, U, E> fmt::Debug for BoxCloneService<T, U, E> {
133 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
134 fmt.debug_struct("BoxCloneService").finish()
135 }
136}