1 use crate::ServiceExt;
2 use tower_layer::{layer_fn, LayerFn};
3 use tower_service::Service;
4 
5 use std::fmt;
6 use std::{
7     future::Future,
8     pin::Pin,
9     task::{Context, Poll},
10 };
11 
12 /// A boxed `Service + Send` trait object.
13 ///
14 /// [`BoxService`] turns a service into a trait object, allowing the response
15 /// future type to be dynamic. This type requires both the service and the
16 /// response future to be [`Send`].
17 ///
18 /// If you need a boxed [`Service`] that implements [`Clone`] consider using
19 /// [`BoxCloneService`](crate::util::BoxCloneService).
20 ///
21 /// See module level documentation for more details.
22 pub struct BoxService<T, U, E> {
23     inner: Box<dyn Service<T, Response = U, Error = E, Future = BoxFuture<U, E>> + Send>,
24 }
25 
26 /// A boxed `Future + Send` trait object.
27 ///
28 /// This type alias represents a boxed future that is [`Send`] and can be moved
29 /// across threads.
30 type BoxFuture<T, E> = Pin<Box<dyn Future<Output = Result<T, E>> + Send>>;
31 
32 impl<T, U, E> BoxService<T, U, E> {
33     #[allow(missing_docs)]
new<S>(inner: S) -> Self where S: Service<T, Response = U, Error = E> + Send + 'static, S::Future: Send + 'static,34     pub fn new<S>(inner: S) -> Self
35     where
36         S: Service<T, Response = U, Error = E> + Send + 'static,
37         S::Future: Send + 'static,
38     {
39         let inner = Box::new(inner.map_future(|f: S::Future| Box::pin(f) as _));
40         BoxService { inner }
41     }
42 
43     /// Returns a [`Layer`] for wrapping a [`Service`] in a [`BoxService`]
44     /// middleware.
45     ///
46     /// [`Layer`]: crate::Layer
layer<S>() -> LayerFn<fn(S) -> Self> where S: Service<T, Response = U, Error = E> + Send + 'static, S::Future: Send + 'static,47     pub fn layer<S>() -> LayerFn<fn(S) -> Self>
48     where
49         S: Service<T, Response = U, Error = E> + Send + 'static,
50         S::Future: Send + 'static,
51     {
52         layer_fn(Self::new)
53     }
54 }
55 
56 impl<T, U, E> Service<T> for BoxService<T, U, E> {
57     type Response = U;
58     type Error = E;
59     type Future = BoxFuture<U, E>;
60 
poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), E>>61     fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), E>> {
62         self.inner.poll_ready(cx)
63     }
64 
call(&mut self, request: T) -> BoxFuture<U, E>65     fn call(&mut self, request: T) -> BoxFuture<U, E> {
66         self.inner.call(request)
67     }
68 }
69 
70 impl<T, U, E> fmt::Debug for BoxService<T, U, E> {
fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result71     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
72         fmt.debug_struct("BoxService").finish()
73     }
74 }
75