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