embedded_fps/
std_clock.rs

1use std::time::Instant as StdInstant;
2
3    use embedded_time::{clock::Error, rate::Fraction, Clock, Instant as EmbeddedInstant};
4
5    /// A Standard clock based on [`std`].
6    ///
7    /// It takes the [`Instant::elapsed()`] time and uses nanoseconds converted to [`u64`].
8    /// This still leaves us with ~594 years of representable time
9    ///
10    /// [`Instant::elapsed()`]: std::time::Instant::elapsed()
11    #[derive(Debug, Clone, Copy)]
12    pub struct StdClock(StdInstant);
13
14    impl Default for StdClock {
15        fn default() -> Self {
16            Self::new()
17        }
18    }
19
20    impl StdClock {
21        /// Creates a new [`StdClock`].
22        /// Internally it calls [`Instant::now()`].
23        ///
24        /// [`Instant::now()`]: std::time::Instant::now()
25        pub fn new() -> Self {
26            Self(StdInstant::now())
27        }
28    }
29
30    impl Clock for StdClock {
31        type T = u64;
32
33        const SCALING_FACTOR: Fraction = Fraction::new(1, 1_000_000_000);
34
35        fn try_now(&self) -> Result<EmbeddedInstant<Self>, Error> {
36            // discarding the upper u64 still leaves us with ~594 years of representable time
37            Ok(EmbeddedInstant::new(self.0.elapsed().as_nanos() as u64))
38        }
39    }
40
41    #[cfg(test)]
42    mod tests {
43        use std::thread::sleep;
44
45        use embedded_time::{
46            duration::{Extensions, Milliseconds},
47            Clock,
48        };
49
50        use super::StdClock;
51
52        #[test]
53        fn it_creates_std_instant_from_milliseconds_clock() {
54            let clock = StdClock::new();
55
56            sleep(std::time::Duration::from_millis(400));
57
58            let start = clock.try_now().unwrap();
59            // wait 1.5 seconds
60            sleep(std::time::Duration::from_millis(1_600));
61            let end = clock.try_now().unwrap();
62
63            let elapsed = Milliseconds::<u64>::try_from(end - start).unwrap();
64
65            let lower_bound = Milliseconds::<u64>::try_from(1_599_u32.milliseconds()).unwrap();
66            assert!(elapsed > lower_bound);
67
68            let upper_bound = Milliseconds::<u64>::try_from(2_000_u32.milliseconds()).unwrap();
69            assert!(elapsed < upper_bound);
70        }
71    }