blockz_futures/
timeout.rs1use std::future::Future;
4use std::pin::Pin;
5use std::task::Context;
6use std::task::Poll;
7use std::time::Duration;
8use std::time::Instant;
9
10use thiserror::Error;
11
12#[derive(Clone, Copy, Debug, Error)]
14#[error("future timed out")]
15pub struct TimedOut(());
16
17#[pin_project]
19pub struct Timeout<F> {
20 #[pin]
21 future: tokio::time::Timeout<F>,
22}
23
24impl<F: Future> Timeout<F> {
25 pub fn new(future: F, timeout: Duration) -> Self {
27 Self {
28 future: tokio::time::timeout(timeout, future),
29 }
30 }
31}
32
33impl<F: Future> Future for Timeout<F> {
34 type Output = Result<F::Output, TimedOut>;
35
36 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
37 let this = self.project();
38 let future: Pin<&mut tokio::time::Timeout<F>> = this.future;
39
40 if let Poll::Ready(result) = future.poll(cx) {
41 match result {
42 Ok(out) => Poll::Ready(Ok(out)),
43 Err(_) => Poll::Ready(Err(TimedOut(()))),
44 }
45 } else {
46 Poll::Pending
47 }
48 }
49}
50
51#[pin_project]
53pub struct Deadline<F> {
54 #[pin]
55 future: tokio::time::Timeout<F>,
56}
57
58impl<F: Future> Deadline<F> {
59 pub fn new(future: F, deadline: Instant) -> Self {
61 Self {
62 future: tokio::time::timeout_at(deadline.into(), future),
63 }
64 }
65}
66
67impl<F: Future> Future for Deadline<F> {
68 type Output = Result<F::Output, TimedOut>;
69
70 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
71 let this = self.project();
72 let future: Pin<&mut tokio::time::Timeout<F>> = this.future;
73
74 if let Poll::Ready(result) = future.poll(cx) {
75 match result {
76 Ok(out) => Poll::Ready(Ok(out)),
77 Err(_) => Poll::Ready(Err(TimedOut(()))),
78 }
79 } else {
80 Poll::Pending
81 }
82 }
83}