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}