| 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<T, Request> { | |
| inner: Option<T>, | |
| _p: PhantomData<fn() -> Request>, | |
| } | |
| // Safety: This is safe because `Services`'s are always `Unpin`. | |
| impl<T, Request> Unpin for ReadyOneshot<T, Request> {} | |
| impl<T, Request> ReadyOneshot<T, Request> | |
| where | |
| T: Service<Request>, | |
| { | |
| #[allow(missing_docs)] | |
| pub fn new(service: T) -> Self { | |
| Self { | |
| inner: Some(service), | |
| _p: PhantomData, | |
| } | |
| } | |
| } | |
| impl<T, Request> Future for ReadyOneshot<T, Request> | |
| where | |
| T: Service<Request>, | |
| { | |
| type Output = Result<T, T::Error>; | |
| fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { | |
| 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<T, Request> fmt::Debug for ReadyOneshot<T, Request> | |
| 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<Request>, | |
| { | |
| #[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<Request>, | |
| { | |
| type Output = Result<&'a mut T, T::Error>; | |
| fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { | |
| 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() | |
| } | |
| } |