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