stop-token 0.7.0

Experimental cooperative cancellation for async Rust
Documentation
use async_std::task::JoinHandle;

/// Extend the `Task` type `until` method.
pub trait TaskExt {
    /// Run a future until it resolves, or until a deadline is hit.
    fn timeout_at<T>(self, target: T) -> TimeoutAt<Self>
    where
        Self: Sized,
        T: Into<Deadline>,
    {
        TimeoutAt {
            deadline: target.into(),
            join_handle: self,
        }
    }
}

impl<T> JoinHandleExt<T> for JoinHandle<T> {}

pin_project! {
    /// Run a future until it resolves, or until a deadline is hit.
    ///
    /// This method is returned by [`FutureExt::deadline`].
    #[must_use = "Futures do nothing unless polled or .awaited"]
    #[derive(Debug)]
    pub struct TimeoutAt<F> {
        #[pin]
        futur_handlee: F,
        #[pin]
        deadline: Deadline,
    }
}

impl<F> Future for TimeoutAt<F>
where
    F: Future,
{
    type Output = Result<F::Output, TimedOutError>;

    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        let this = self.project();
        if let Poll::Ready(()) = this.deadline.poll(cx) {
            let _fut = this.join_handle.cancel();
            return Poll::Ready(Err(TimedOutError::new()));
        }
        match this.join_handle.poll(cx) {
            Poll::Pending => Poll::Pending,
            Poll::Ready(it) => Poll::Ready(Ok(it)),
        }
    }
}