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
11pub struct ReadyOneshot<T, Request> {
17 inner: Option<T>,
18 _p: PhantomData<fn() -> Request>,
19}
20
21impl<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
65pub struct Ready<'a, T, Request>(ReadyOneshot<&'a mut T, Request>);
71
72impl<'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}