use futures_core::TryFuture; use futures_util::{future, TryFutureExt}; use std::fmt; use std::future::Future; use std::pin::Pin; use std::task::{Context, Poll}; use tower_layer::Layer; use tower_service::Service; /// Service returned by the [`and_then`] combinator. /// /// [`and_then`]: crate::util::ServiceExt::and_then #[derive(Clone)] pub struct AndThen { inner: S, f: F, } impl fmt::Debug for AndThen where S: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("AndThen") .field("inner", &self.inner) .field("f", &format_args!("{}", std::any::type_name::())) .finish() } } pin_project_lite::pin_project! { /// Response future from [`AndThen`] services. /// /// [`AndThen`]: crate::util::AndThen pub struct AndThenFuture { #[pin] inner: future::AndThen, F2, N>, } } impl AndThenFuture { pub(crate) fn new(inner: future::AndThen, F2, N>) -> Self { Self { inner } } } impl std::fmt::Debug for AndThenFuture { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_tuple("AndThenFuture") .field(&format_args!("...")) .finish() } } impl Future for AndThenFuture where future::AndThen, F2, N>: Future, { type Output = , F2, N> as Future>::Output; #[inline] fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { self.project().inner.poll(cx) } } /// A [`Layer`] that produces a [`AndThen`] service. /// /// [`Layer`]: tower_layer::Layer #[derive(Clone, Debug)] pub struct AndThenLayer { f: F, } impl AndThen { /// Creates a new `AndThen` service. pub fn new(inner: S, f: F) -> Self { AndThen { f, inner } } /// Returns a new [`Layer`] that produces [`AndThen`] services. /// /// This is a convenience function that simply calls [`AndThenLayer::new`]. /// /// [`Layer`]: tower_layer::Layer pub fn layer(f: F) -> AndThenLayer { AndThenLayer { f } } } impl Service for AndThen where S: Service, S::Error: Into, F: FnOnce(S::Response) -> Fut + Clone, Fut: TryFuture, { type Response = Fut::Ok; type Error = Fut::Error; type Future = AndThenFuture; fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { self.inner.poll_ready(cx).map_err(Into::into) } fn call(&mut self, request: Request) -> Self::Future { AndThenFuture::new(self.inner.call(request).err_into().and_then(self.f.clone())) } } impl AndThenLayer { /// Creates a new [`AndThenLayer`] layer. pub fn new(f: F) -> Self { AndThenLayer { f } } } impl Layer for AndThenLayer where F: Clone, { type Service = AndThen; fn layer(&self, inner: S) -> Self::Service { AndThen { f: self.f.clone(), inner, } } }