use async_std::task::JoinHandle;
pub trait TaskExt {
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! {
#[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)),
}
}
}