moirai_async/timer/
timeout.rs1use std::future::Future;
2use std::pin::Pin;
3use std::task::{Context, Poll};
4use std::time::Duration;
5
6use crate::timer::delay::Delay;
7
8pub struct Timeout<F> {
10 future: F,
11 delay: Delay,
12}
13
14impl<F> Timeout<F>
15where
16 F: Future,
17{
18 pub(super) fn new(future: F, duration: Duration) -> Self {
19 Self {
20 future,
21 delay: Delay::new(duration),
22 }
23 }
24}
25
26impl<F> Future for Timeout<F>
27where
28 F: Future,
29{
30 type Output = Result<F::Output, TimeoutError>;
31
32 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
33 let this = unsafe { self.get_unchecked_mut() };
37
38 let future = unsafe { Pin::new_unchecked(&mut this.future) };
40 if let Poll::Ready(output) = future.poll(cx) {
41 return Poll::Ready(Ok(output));
42 }
43
44 if let Poll::Ready(()) = Pin::new(&mut this.delay).poll(cx) {
46 return Poll::Ready(Err(TimeoutError));
47 }
48
49 Poll::Pending
50 }
51}
52
53#[derive(Debug, Clone, Copy, PartialEq, Eq)]
55pub struct TimeoutError;
56
57impl std::fmt::Display for TimeoutError {
58 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
59 f.write_str("operation timed out")
60 }
61}
62
63impl std::error::Error for TimeoutError {}