timeout_trait/
std_impls.rs

1use super::{
2    fugit::{KilohertzU32, RateExtU32},
3    prelude::*,
4};
5use std::time::{Duration, Instant};
6
7/// [`TimeoutNs`] implementation.
8#[derive(Default)]
9pub struct StdTimeoutNs {}
10
11impl TimeoutNs for StdTimeoutNs {
12    fn start_ns(timeout: u32) -> impl TimeoutState {
13        StdTimeoutState {
14            timeout: Duration::from_nanos(timeout.into()),
15            start_time: Instant::now(),
16        }
17    }
18
19    fn start_us(timeout: u32) -> impl TimeoutState {
20        StdTimeoutState {
21            timeout: Duration::from_micros(timeout.into()),
22            start_time: Instant::now(),
23        }
24    }
25
26    fn start_ms(timeout: u32) -> impl TimeoutState {
27        StdTimeoutState {
28            timeout: Duration::from_millis(timeout.into()),
29            start_time: Instant::now(),
30        }
31    }
32}
33
34/// [`TimeoutState`] implementation for.
35pub struct StdTimeoutState {
36    timeout: Duration,
37    start_time: Instant,
38}
39
40impl TimeoutState for StdTimeoutState {
41    #[inline]
42    fn timeout(&mut self) -> bool {
43        if self.start_time.elapsed() >= self.timeout {
44            self.start_time += self.timeout;
45            true
46        } else {
47            false
48        }
49    }
50
51    #[inline(always)]
52    fn restart(&mut self) {
53        self.start_time = Instant::now();
54    }
55}
56
57impl TickInstant for Instant {
58    fn frequency() -> KilohertzU32 {
59        1.MHz()
60    }
61
62    #[inline(always)]
63    fn now() -> Self {
64        Instant::now()
65    }
66
67    #[inline(always)]
68    fn tick_since(self, earlier: Self) -> u32 {
69        self.duration_since(earlier).as_micros() as u32
70    }
71}
72
73#[cfg(test)]
74mod tests {
75    use super::*;
76    use crate::TickTimeoutNs;
77    use std::{thread::sleep, time::Duration};
78
79    fn test_timeout<T: TimeoutNs>() {
80        let mut t = T::start_ms(500);
81        assert!(!t.timeout());
82        sleep(Duration::from_millis(260));
83        assert!(!t.timeout());
84        sleep(Duration::from_millis(260));
85        assert!(t.timeout());
86        assert!(!t.timeout());
87
88        t.restart();
89        assert!(!t.timeout());
90        sleep(Duration::from_millis(260));
91        assert!(!t.timeout());
92        sleep(Duration::from_millis(260));
93        assert!(t.timeout());
94        assert!(!t.timeout());
95
96        assert!(T::ns_with(100, || {
97            sleep(Duration::from_nanos(1));
98            true
99        }));
100    }
101
102    #[test]
103    fn std_timeout() {
104        test_timeout::<StdTimeoutNs>();
105    }
106
107    #[test]
108    fn tick_timeout() {
109        test_timeout::<TickTimeoutNs<Instant>>();
110    }
111
112    #[test]
113    fn tick_instant() {
114        let now = <Instant as TickInstant>::now();
115        sleep(Duration::from_millis(200));
116        assert!(now.tick_elapsed() - 200_000 < 1000);
117    }
118}