//! Contains [`Optional`] and related types and functions. //! //! See [`Optional`] documentation for more details. /// Error types for [`Optional`]. pub mod error; /// Future types for [`Optional`]. pub mod future; use self::future::ResponseFuture; use std::task::{Context, Poll}; use tower_service::Service; /// Optionally forwards requests to an inner service. /// /// If the inner service is [`None`], [`optional::None`] is returned as the response. /// /// [`optional::None`]: crate::util::error::optional::None #[derive(Debug)] pub struct Optional { inner: Option, } impl Optional { /// Create a new [`Optional`]. pub fn new(inner: Option) -> Optional where T: Service, T::Error: Into, { Optional { inner } } } impl Service for Optional where T: Service, T::Error: Into, { type Response = T::Response; type Error = crate::BoxError; type Future = ResponseFuture; fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { match self.inner { Some(ref mut inner) => match inner.poll_ready(cx) { Poll::Ready(r) => Poll::Ready(r.map_err(Into::into)), Poll::Pending => Poll::Pending, }, // None services are always ready None => Poll::Ready(Ok(())), } } fn call(&mut self, request: Request) -> Self::Future { let inner = self.inner.as_mut().map(|i| i.call(request)); ResponseFuture::new(inner) } }