std_embedded_time/lib.rs
1//! # Standard `embedded-time`
2//!
3//! This library provides an [embedded_time::Clock] that can be used for host-side testing.
4//!
5//! The provided [embedded_time::Clock] implementation is based on [std::time].
6//!
7//! # Usage
8//!
9//! ```rust
10//! use std_embedded_time::StandardClock;
11//! use embedded_time::Clock;
12//!
13//! fn main() {
14//! let clock = StandardClock::default();
15//!
16//! let now = clock.try_now().unwrap();
17//! println!("Current time: {:?}", now);
18//! }
19//! ```
20
21pub use embedded_time;
22
23use embedded_time::{fraction::Fraction, Instant};
24
25/// A clock with nanosecond precision.
26///
27/// To construct a clock, use [StandardClock::default()].
28///
29/// The clock is "started" when it is constructed.
30///
31/// # Limitations
32/// The clock represents up to ~584 years worth of time, after which it will roll over.
33#[derive(Copy, Clone, Debug)]
34pub struct StandardClock {
35 start: std::time::Instant,
36}
37
38impl Default for StandardClock {
39 fn default() -> Self {
40 Self {
41 start: std::time::Instant::now(),
42 }
43 }
44}
45
46impl embedded_time::Clock for StandardClock {
47 /// With a 64-bit tick register, the clock can represent times up to approximately 594 years in
48 /// duration, after which the clock will roll over.
49 type T = u64;
50
51 /// Each tick of the clock is equivalent to 1 nanosecond.
52 const SCALING_FACTOR: Fraction = Fraction::new(1, 1_000_000_000);
53
54 /// Get the current time from the clock.
55 fn try_now(&self) -> Result<Instant<Self>, embedded_time::clock::Error> {
56 let now = std::time::Instant::now();
57
58 let elapsed = now.duration_since(self.start);
59
60 // Note: We are discarding the upper 64 bits of nanoseconds. However, even while doing so,
61 // we can represent ~594 years of time, so this should not be relevant.
62 Ok(Instant::new(elapsed.as_nanos() as u64))
63 }
64}
65
66#[cfg(test)]
67mod test {
68 use super::StandardClock;
69 use core::convert::TryFrom;
70 use embedded_time::{duration::*, Clock};
71 use std::time::Duration;
72
73 #[test]
74 fn test_measurement() {
75 let clock = StandardClock::default();
76
77 let start = clock.try_now().unwrap();
78 std::thread::sleep(Duration::from_secs(1));
79 let end = clock.try_now().unwrap();
80
81 let elapsed = end - start;
82
83 let lower_bound = Milliseconds::<u64>::try_from(999u32.milliseconds()).unwrap();
84 assert!(elapsed > lower_bound.into());
85
86 let upper_bound = Milliseconds::<u64>::try_from(2000u32.milliseconds()).unwrap();
87 assert!(elapsed < upper_bound.into());
88 }
89}