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