do_not_use_testing_rclrs/
time.rs

1use crate::rcl_bindings::*;
2use std::ops::{Add, Sub};
3use std::sync::{Mutex, Weak};
4use std::time::Duration;
5
6/// Struct that represents time.
7#[derive(Clone, Debug)]
8pub struct Time {
9    /// Timestamp in nanoseconds.
10    pub nsec: i64,
11    /// Weak reference to the clock that generated this time
12    pub clock: Weak<Mutex<rcl_clock_t>>,
13}
14
15impl Time {
16    /// Compares self to rhs, if they can be compared (originated from the same clock) calls f with
17    /// the values of the timestamps.
18    pub fn compare_with<U, F>(&self, rhs: &Time, f: F) -> Option<U>
19    where
20        F: FnOnce(i64, i64) -> U,
21    {
22        self.clock
23            .ptr_eq(&rhs.clock)
24            .then(|| f(self.nsec, rhs.nsec))
25    }
26}
27
28impl Add<Duration> for Time {
29    type Output = Self;
30
31    fn add(self, other: Duration) -> Self {
32        let dur_ns = i64::try_from(other.as_nanos()).unwrap();
33        Time {
34            nsec: self.nsec.checked_add(dur_ns).unwrap(),
35            clock: self.clock.clone(),
36        }
37    }
38}
39
40impl Sub<Duration> for Time {
41    type Output = Self;
42
43    fn sub(self, other: Duration) -> Self {
44        let dur_ns = i64::try_from(other.as_nanos()).unwrap();
45        Time {
46            nsec: self.nsec.checked_sub(dur_ns).unwrap(),
47            clock: self.clock.clone(),
48        }
49    }
50}
51
52#[cfg(test)]
53mod tests {
54    use super::*;
55    use crate::Clock;
56
57    #[test]
58    fn compare_times_from_same_clock() {
59        let clock = Clock::system();
60        let t1 = clock.now();
61        std::thread::sleep(std::time::Duration::from_micros(1));
62        let t2 = clock.now();
63        assert_eq!(t1.compare_with(&t2, |t1, t2| t1 > t2), Some(false));
64        assert_eq!(t1.compare_with(&t2, |t1, t2| t2 > t1), Some(true));
65    }
66
67    #[test]
68    fn compare_times_from_different_clocks() {
69        // Times from different clocks, even if of the same type, can't be compared
70        let c1 = Clock::system();
71        let c2 = Clock::system();
72        let t1 = c1.now();
73        let t2 = c2.now();
74        assert!(t2.compare_with(&t1, |_, _| ()).is_none());
75        assert!(t1.compare_with(&t2, |_, _| ()).is_none());
76    }
77
78    #[test]
79    fn add_duration_to_time() {
80        let (clock, _) = Clock::with_source();
81        let t = clock.now();
82        let t2 = t.clone() + Duration::from_secs(1);
83        assert_eq!(t2.nsec - t.nsec, 1_000_000_000i64);
84        let t3 = t2 - Duration::from_secs(1);
85        assert_eq!(t3.nsec, t.nsec);
86    }
87}