agnostic_lite/embassy/
timeout.rs1use core::{
2 future::Future,
3 pin::Pin,
4 task::{Context, Poll},
5 time::Duration,
6};
7
8use embassy_time::Timer;
9
10use crate::time::{AsyncLocalTimeout, AsyncTimeout, Elapsed};
11
12use super::{Instant, to_embassy_duration};
13
14pin_project_lite::pin_project! {
15 pub struct EmbassyTimeout<F> {
17 #[pin]
18 future: F,
19 #[pin]
20 delay: Timer,
21 }
22}
23
24impl<F: Future> Future for EmbassyTimeout<F> {
25 type Output = Result<F::Output, Elapsed>;
26
27 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
28 let this = self.project();
29 match this.future.poll(cx) {
30 Poll::Ready(v) => Poll::Ready(Ok(v)),
31 Poll::Pending => match this.delay.poll(cx) {
32 Poll::Ready(()) => Poll::Ready(Err(Elapsed)),
33 Poll::Pending => Poll::Pending,
34 },
35 }
36 }
37}
38
39impl<F: Future + Send> AsyncTimeout<F> for EmbassyTimeout<F> {
40 type Instant = Instant;
41
42 fn timeout(t: Duration, fut: F) -> Self
43 where
44 Self: Sized,
45 {
46 <Self as AsyncLocalTimeout<F>>::timeout_local(t, fut)
47 }
48
49 fn timeout_at(deadline: Instant, fut: F) -> Self
50 where
51 Self: Sized,
52 {
53 <Self as AsyncLocalTimeout<F>>::timeout_local_at(deadline, fut)
54 }
55}
56
57impl<F: Future> AsyncLocalTimeout<F> for EmbassyTimeout<F> {
58 type Instant = Instant;
59
60 fn timeout_local(timeout: Duration, fut: F) -> Self
61 where
62 Self: Sized,
63 {
64 Self {
65 future: fut,
66 delay: Timer::after(to_embassy_duration(timeout)),
67 }
68 }
69
70 fn timeout_local_at(deadline: Instant, fut: F) -> Self
71 where
72 Self: Sized,
73 {
74 Self {
75 future: fut,
76 delay: Timer::at(deadline.into_embassy()),
77 }
78 }
79}