1 //! Contains [`Optional`] and related types and functions. 2 //! 3 //! See [`Optional`] documentation for more details. 4 5 /// Error types for [`Optional`]. 6 pub mod error; 7 /// Future types for [`Optional`]. 8 pub mod future; 9 10 use self::future::ResponseFuture; 11 use std::task::{Context, Poll}; 12 use tower_service::Service; 13 14 /// Optionally forwards requests to an inner service. 15 /// 16 /// If the inner service is [`None`], [`optional::None`] is returned as the response. 17 /// 18 /// [`optional::None`]: crate::util::error::optional::None 19 #[derive(Debug)] 20 pub struct Optional<T> { 21 inner: Option<T>, 22 } 23 24 impl<T> Optional<T> { 25 /// Create a new [`Optional`]. new<Request>(inner: Option<T>) -> Optional<T> where T: Service<Request>, T::Error: Into<crate::BoxError>,26 pub fn new<Request>(inner: Option<T>) -> Optional<T> 27 where 28 T: Service<Request>, 29 T::Error: Into<crate::BoxError>, 30 { 31 Optional { inner } 32 } 33 } 34 35 impl<T, Request> Service<Request> for Optional<T> 36 where 37 T: Service<Request>, 38 T::Error: Into<crate::BoxError>, 39 { 40 type Response = T::Response; 41 type Error = crate::BoxError; 42 type Future = ResponseFuture<T::Future>; 43 poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>44 fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { 45 match self.inner { 46 Some(ref mut inner) => match inner.poll_ready(cx) { 47 Poll::Ready(r) => Poll::Ready(r.map_err(Into::into)), 48 Poll::Pending => Poll::Pending, 49 }, 50 // None services are always ready 51 None => Poll::Ready(Ok(())), 52 } 53 } 54 call(&mut self, request: Request) -> Self::Future55 fn call(&mut self, request: Request) -> Self::Future { 56 let inner = self.inner.as_mut().map(|i| i.call(request)); 57 ResponseFuture::new(inner) 58 } 59 } 60