tower/util/
ready.rs

1use std::{fmt, marker::PhantomData};
2
3use futures_core::ready;
4use std::{
5    future::Future,
6    pin::Pin,
7    task::{Context, Poll},
8};
9use tower_service::Service;
10
11/// A [`Future`] that yields the service when it is ready to accept a request.
12///
13/// [`ReadyOneshot`] values are produced by [`ServiceExt::ready_oneshot`].
14///
15/// [`ServiceExt::ready_oneshot`]: crate::util::ServiceExt::ready_oneshot
16pub struct ReadyOneshot<T, Request> {
17    inner: Option<T>,
18    _p: PhantomData<fn() -> Request>,
19}
20
21// Safety: This is safe because `Services`'s are always `Unpin`.
22impl<T, Request> Unpin for ReadyOneshot<T, Request> {}
23
24impl<T, Request> ReadyOneshot<T, Request>
25where
26    T: Service<Request>,
27{
28    #[allow(missing_docs)]
29    pub const fn new(service: T) -> Self {
30        Self {
31            inner: Some(service),
32            _p: PhantomData,
33        }
34    }
35}
36
37impl<T, Request> Future for ReadyOneshot<T, Request>
38where
39    T: Service<Request>,
40{
41    type Output = Result<T, T::Error>;
42
43    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
44        ready!(self
45            .inner
46            .as_mut()
47            .expect("poll after Poll::Ready")
48            .poll_ready(cx))?;
49
50        Poll::Ready(Ok(self.inner.take().expect("poll after Poll::Ready")))
51    }
52}
53
54impl<T, Request> fmt::Debug for ReadyOneshot<T, Request>
55where
56    T: fmt::Debug,
57{
58    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
59        f.debug_struct("ReadyOneshot")
60            .field("inner", &self.inner)
61            .finish()
62    }
63}
64
65/// A future that yields a mutable reference to the service when it is ready to accept a request.
66///
67/// [`Ready`] values are produced by [`ServiceExt::ready`].
68///
69/// [`ServiceExt::ready`]: crate::util::ServiceExt::ready
70pub struct Ready<'a, T, Request>(ReadyOneshot<&'a mut T, Request>);
71
72// Safety: This is safe for the same reason that the impl for ReadyOneshot is safe.
73impl<'a, T, Request> Unpin for Ready<'a, T, Request> {}
74
75impl<'a, T, Request> Ready<'a, T, Request>
76where
77    T: Service<Request>,
78{
79    #[allow(missing_docs)]
80    pub fn new(service: &'a mut T) -> Self {
81        Self(ReadyOneshot::new(service))
82    }
83}
84
85impl<'a, T, Request> Future for Ready<'a, T, Request>
86where
87    T: Service<Request>,
88{
89    type Output = Result<&'a mut T, T::Error>;
90
91    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
92        Pin::new(&mut self.0).poll(cx)
93    }
94}
95
96impl<'a, T, Request> fmt::Debug for Ready<'a, T, Request>
97where
98    T: fmt::Debug,
99{
100    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
101        f.debug_tuple("Ready").field(&self.0).finish()
102    }
103}