• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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