use std::{fmt, marker::PhantomData}; use futures_core::ready; use std::{ future::Future, pin::Pin, task::{Context, Poll}, }; use tower_service::Service; /// A [`Future`] that yields the service when it is ready to accept a request. /// /// [`ReadyOneshot`] values are produced by [`ServiceExt::ready_oneshot`]. /// /// [`ServiceExt::ready_oneshot`]: crate::util::ServiceExt::ready_oneshot pub struct ReadyOneshot { inner: Option, _p: PhantomData Request>, } // Safety: This is safe because `Services`'s are always `Unpin`. impl Unpin for ReadyOneshot {} impl ReadyOneshot where T: Service, { #[allow(missing_docs)] pub fn new(service: T) -> Self { Self { inner: Some(service), _p: PhantomData, } } } impl Future for ReadyOneshot where T: Service, { type Output = Result; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { ready!(self .inner .as_mut() .expect("poll after Poll::Ready") .poll_ready(cx))?; Poll::Ready(Ok(self.inner.take().expect("poll after Poll::Ready"))) } } impl fmt::Debug for ReadyOneshot where T: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("ReadyOneshot") .field("inner", &self.inner) .finish() } } /// A future that yields a mutable reference to the service when it is ready to accept a request. /// /// [`Ready`] values are produced by [`ServiceExt::ready`]. /// /// [`ServiceExt::ready`]: crate::util::ServiceExt::ready pub struct Ready<'a, T, Request>(ReadyOneshot<&'a mut T, Request>); /// A future that yields a mutable reference to the service when it is ready to accept a request. /// /// [`ReadyAnd`] values are produced by [`ServiceExt::ready_and`]. /// /// [`ServiceExt::ready_and`]: crate::util::ServiceExt::ready_and #[deprecated(since = "0.4.6", note = "Please use the Ready future instead")] pub type ReadyAnd<'a, T, Request> = Ready<'a, T, Request>; // Safety: This is safe for the same reason that the impl for ReadyOneshot is safe. impl<'a, T, Request> Unpin for Ready<'a, T, Request> {} impl<'a, T, Request> Ready<'a, T, Request> where T: Service, { #[allow(missing_docs)] pub fn new(service: &'a mut T) -> Self { Self(ReadyOneshot::new(service)) } } impl<'a, T, Request> Future for Ready<'a, T, Request> where T: Service, { type Output = Result<&'a mut T, T::Error>; fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { Pin::new(&mut self.0).poll(cx) } } impl<'a, T, Request> fmt::Debug for Ready<'a, T, Request> where T: fmt::Debug, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_tuple("Ready").field(&self.0).finish() } }