| //! Future types |
| |
| use super::error::Elapsed; |
| use pin_project_lite::pin_project; |
| use std::{ |
| future::Future, |
| pin::Pin, |
| task::{Context, Poll}, |
| }; |
| use tokio::time::Sleep; |
| |
| pin_project! { |
| /// [`Timeout`] response future |
| /// |
| /// [`Timeout`]: crate::timeout::Timeout |
| #[derive(Debug)] |
| pub struct ResponseFuture<T> { |
| #[pin] |
| response: T, |
| #[pin] |
| sleep: Sleep, |
| } |
| } |
| |
| impl<T> ResponseFuture<T> { |
| pub(crate) fn new(response: T, sleep: Sleep) -> Self { |
| ResponseFuture { response, sleep } |
| } |
| } |
| |
| impl<F, T, E> Future for ResponseFuture<F> |
| where |
| F: Future<Output = Result<T, E>>, |
| E: Into<crate::BoxError>, |
| { |
| type Output = Result<T, crate::BoxError>; |
| |
| fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
| let this = self.project(); |
| |
| // First, try polling the future |
| match this.response.poll(cx) { |
| Poll::Ready(v) => return Poll::Ready(v.map_err(Into::into)), |
| Poll::Pending => {} |
| } |
| |
| // Now check the sleep |
| match this.sleep.poll(cx) { |
| Poll::Pending => Poll::Pending, |
| Poll::Ready(_) => Poll::Ready(Err(Elapsed(()).into())), |
| } |
| } |
| } |