1use core::{
2 pin::Pin,
3 task::{Context, Poll},
4};
5use futures::{Future, FutureExt, Stream};
6
7pub use embedded_hal::timer::Periodic;
8
9mod ready;
10pub use ready::{ready, AlreadyStarted, Ready};
11
12#[cfg(feature = "nb")]
13mod timer;
14#[cfg(feature = "nb")]
15pub use timer::Timer;
16
17pub trait DelayMs {
18 type Delay;
20
21 type Error;
23
24 fn start(&mut self, ms: Self::Delay) -> Result<(), Self::Error>;
26
27 fn poll_delay_ms(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), Self::Error>>;
30
31 fn cancel(&mut self) -> Result<(), Self::Error>;
33
34 fn poll_delay_ms_unpin(&mut self, cx: &mut Context) -> Poll<Result<(), Self::Error>>
35 where
36 Self: Unpin,
37 {
38 Pin::new(self).poll_delay_ms(cx)
39 }
40
41 fn delay_ms(&mut self, ms: Self::Delay) -> DelayMsFuture<Self>
47 where
48 Self: Unpin,
49 {
50 DelayMsFuture {
51 timer: self,
52 ms: Some(ms),
53 is_started: false,
54 }
55 }
56}
57
58pub struct DelayMsFuture<'a, T: ?Sized + DelayMs> {
59 timer: &'a mut T,
60 ms: Option<T::Delay>,
61 is_started: bool,
62}
63
64impl<T> Future for DelayMsFuture<'_, T>
65where
66 T: ?Sized + DelayMs + Unpin,
67 T::Delay: Unpin,
68{
69 type Output = Result<(), T::Error>;
70
71 fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
72 if !self.is_started {
73 let ms = self.ms.take().unwrap();
74 self.timer.start(ms)?;
75
76 self.is_started = true;
77 }
78
79 self.timer.poll_delay_ms_unpin(cx)
80 }
81}
82
83impl<T> Stream for DelayMsFuture<'_, T>
84where
85 T: ?Sized + Periodic + DelayMs + Unpin,
86 T::Delay: Unpin,
87{
88 type Item = Result<(), T::Error>;
89
90 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
91 self.poll_unpin(cx).map(Some)
92 }
93}
94
95impl<T> Drop for DelayMsFuture<'_, T>
96where
97 T: ?Sized + DelayMs,
98{
99 fn drop(&mut self) {
100 self.timer.cancel().ok();
101 }
102}