timeout_trait/
delay.rs

1use crate::TickDuration;
2
3use super::{embedded_hal::delay::DelayNs, prelude::*};
4use core::marker::PhantomData;
5
6/// [`DelayNs`] implementation
7pub struct TickDelay<T> {
8    _t: PhantomData<T>,
9}
10
11impl<T> Default for TickDelay<T>
12where
13    T: TickInstant,
14{
15    fn default() -> Self {
16        Self { _t: PhantomData }
17    }
18}
19
20impl<T> DelayNs for TickDelay<T>
21where
22    T: TickInstant,
23{
24    #[inline]
25    fn delay_ns(&mut self, ns: u32) {
26        let mut t = T::now();
27        let dur = TickDuration::<T>::from_nanos(ns);
28        while !t.timeout(&dur) {
29            // For unit test
30            #[cfg(feature = "std")]
31            std::thread::sleep(std::time::Duration::from_nanos(1));
32        }
33    }
34}
35
36#[cfg(feature = "std")]
37pub use for_std::*;
38#[cfg(feature = "std")]
39mod for_std {
40    use super::*;
41    use std::time::Duration;
42
43    #[derive(Default)]
44    pub struct StdDelayNs {}
45
46    impl DelayNs for StdDelayNs {
47        #[inline]
48        fn delay_ns(&mut self, ns: u32) {
49            std::thread::sleep(Duration::from_nanos(ns.into()))
50        }
51    }
52
53    #[cfg(test)]
54    mod tests {
55        use super::*;
56        use crate::std_impls::StdTickInstant;
57        use std::time::{Duration, Instant};
58
59        fn test_delay(mut d: impl DelayNs) {
60            let t = Instant::now();
61            d.delay_ns(200_000_000);
62            let elapsed = t.elapsed();
63            assert!(elapsed - Duration::from_millis(200) < Duration::from_millis(100));
64
65            let t = Instant::now();
66            d.delay_us(200_000);
67            let elapsed = t.elapsed();
68            assert!(elapsed - Duration::from_millis(200) < Duration::from_millis(100));
69
70            let t = Instant::now();
71            d.delay_ms(500);
72            let elapsed = t.elapsed();
73            assert!(elapsed - Duration::from_millis(500) < Duration::from_millis(100));
74        }
75
76        #[test]
77        fn std_delay() {
78            let d = StdDelayNs::default();
79            test_delay(d);
80        }
81
82        #[test]
83        fn tick_delay() {
84            let d = TickDelay::<StdTickInstant>::default();
85            test_delay(d);
86        }
87    }
88}