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