timeout_trait/
std_impls.rs1use super::{
2 fugit::{KilohertzU32, RateExtU32},
3 prelude::*,
4};
5use std::time::{Duration, Instant};
6
7#[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
34pub 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}