Skip to main content

leodos_protocols/utils/
clock.rs

1//! Monotonic clock abstraction for time-dependent routing
2//! and protocol decisions.
3
4use core::cell::Cell;
5
6/// Provides the current time in seconds.
7pub trait Clock {
8    /// Returns the current time in seconds since an
9    /// arbitrary epoch.
10    fn now(&self) -> u32;
11}
12
13/// A fixed clock that always returns the same value.
14///
15/// Useful for testing or when time-dependent routing is
16/// not needed.
17pub struct FixedClock(Cell<u32>);
18
19impl FixedClock {
20    /// Creates a fixed clock at the given time.
21    pub fn new(time_s: u32) -> Self {
22        Self(Cell::new(time_s))
23    }
24
25    /// Updates the fixed time value.
26    pub fn set(&self, time_s: u32) {
27        self.0.set(time_s);
28    }
29}
30
31impl Clock for FixedClock {
32    fn now(&self) -> u32 {
33        self.0.get()
34    }
35}
36
37/// Clock backed by cFS Mission Elapsed Time (counts from 0).
38#[cfg(feature = "cfs")]
39pub struct MetClock;
40
41#[cfg(feature = "cfs")]
42impl MetClock {
43    /// Creates a new MET clock.
44    pub fn new() -> Self {
45        Self
46    }
47}
48
49#[cfg(feature = "cfs")]
50impl Clock for MetClock {
51    fn now(&self) -> u32 {
52        leodos_libcfs::cfe::time::SysTime::now_met().seconds()
53    }
54}
55
56/// Clock backed by cFS spacecraft time (TAI or UTC,
57/// depending on mission config).
58#[cfg(feature = "cfs")]
59pub struct SysTimeClock;
60
61#[cfg(feature = "cfs")]
62impl SysTimeClock {
63    /// Creates a new spacecraft time clock.
64    pub fn new() -> Self {
65        Self
66    }
67}
68
69#[cfg(feature = "cfs")]
70impl Clock for SysTimeClock {
71    fn now(&self) -> u32 {
72        leodos_libcfs::cfe::time::SysTime::now().seconds()
73    }
74}
75
76/// Clock backed by `std::time::Instant`.
77#[cfg(feature = "std")]
78pub struct StdClock {
79    epoch: std::time::Instant,
80}
81
82#[cfg(feature = "std")]
83impl StdClock {
84    /// Creates a clock starting from now.
85    pub fn new() -> Self {
86        Self {
87            epoch: std::time::Instant::now(),
88        }
89    }
90}
91
92#[cfg(feature = "std")]
93impl Clock for StdClock {
94    fn now(&self) -> u32 {
95        self.epoch.elapsed().as_secs() as u32
96    }
97}