1 use std::{fmt, marker::PhantomData};
2 
3 use futures_core::ready;
4 use std::{
5     future::Future,
6     pin::Pin,
7     task::{Context, Poll},
8 };
9 use 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
16 pub 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`.
22 impl<T, Request> Unpin for ReadyOneshot<T, Request> {}
23 
24 impl<T, Request> ReadyOneshot<T, Request>
25 where
26     T: Service<Request>,
27 {
28     #[allow(missing_docs)]
new(service: T) -> Self29     pub fn new(service: T) -> Self {
30         Self {
31             inner: Some(service),
32             _p: PhantomData,
33         }
34     }
35 }
36 
37 impl<T, Request> Future for ReadyOneshot<T, Request>
38 where
39     T: Service<Request>,
40 {
41     type Output = Result<T, T::Error>;
42 
poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>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 
54 impl<T, Request> fmt::Debug for ReadyOneshot<T, Request>
55 where
56     T: fmt::Debug,
57 {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result58     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
70 pub struct Ready<'a, T, Request>(ReadyOneshot<&'a mut T, Request>);
71 
72 /// A future that yields a mutable reference to the service when it is ready to accept a request.
73 ///
74 /// [`ReadyAnd`] values are produced by [`ServiceExt::ready_and`].
75 ///
76 /// [`ServiceExt::ready_and`]: crate::util::ServiceExt::ready_and
77 #[deprecated(since = "0.4.6", note = "Please use the Ready future instead")]
78 pub type ReadyAnd<'a, T, Request> = Ready<'a, T, Request>;
79 
80 // Safety: This is safe for the same reason that the impl for ReadyOneshot is safe.
81 impl<'a, T, Request> Unpin for Ready<'a, T, Request> {}
82 
83 impl<'a, T, Request> Ready<'a, T, Request>
84 where
85     T: Service<Request>,
86 {
87     #[allow(missing_docs)]
new(service: &'a mut T) -> Self88     pub fn new(service: &'a mut T) -> Self {
89         Self(ReadyOneshot::new(service))
90     }
91 }
92 
93 impl<'a, T, Request> Future for Ready<'a, T, Request>
94 where
95     T: Service<Request>,
96 {
97     type Output = Result<&'a mut T, T::Error>;
98 
poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>99     fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
100         Pin::new(&mut self.0).poll(cx)
101     }
102 }
103 
104 impl<'a, T, Request> fmt::Debug for Ready<'a, T, Request>
105 where
106     T: fmt::Debug,
107 {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result108     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
109         f.debug_tuple("Ready").field(&self.0).finish()
110     }
111 }
112