use futures_util::{future, FutureExt}; use std::{ fmt, future::Future, task::{Context, Poll}, }; use tower_layer::Layer; use tower_service::Service; /// [`Service`] returned by the [`then`] combinator. /// /// [`then`]: crate::util::ServiceExt::then #[derive(Clone)] pub struct Then { inner: S, f: F, } impl fmt::Debug for Then where S: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Then") .field("inner", &self.inner) .field("f", &format_args!("{}", std::any::type_name::())) .finish() } } /// A [`Layer`] that produces a [`Then`] service. /// /// [`Layer`]: tower_layer::Layer #[derive(Debug, Clone)] pub struct ThenLayer { f: F, } impl Then { /// Creates a new `Then` service. pub fn new(inner: S, f: F) -> Self { Then { f, inner } } /// Returns a new [`Layer`] that produces [`Then`] services. /// /// This is a convenience function that simply calls [`ThenLayer::new`]. /// /// [`Layer`]: tower_layer::Layer pub fn layer(f: F) -> ThenLayer { ThenLayer { f } } } opaque_future! { /// Response future from [`Then`] services. /// /// [`Then`]: crate::util::Then pub type ThenFuture = future::Then; } impl Service for Then where S: Service, S::Error: Into, F: FnOnce(Result) -> Fut + Clone, Fut: Future>, { type Response = Response; type Error = Error; type Future = ThenFuture; #[inline] fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { self.inner.poll_ready(cx).map_err(Into::into) } #[inline] fn call(&mut self, request: Request) -> Self::Future { ThenFuture::new(self.inner.call(request).then(self.f.clone())) } } impl ThenLayer { /// Creates a new [`ThenLayer`] layer. pub fn new(f: F) -> Self { ThenLayer { f } } } impl Layer for ThenLayer where F: Clone, { type Service = Then; fn layer(&self, inner: S) -> Self::Service { Then { f: self.f.clone(), inner, } } }