redux/
timestamp.rs

1pub use crate::instant::Instant;
2use std::time::Duration;
3
4#[cfg(not(target_arch = "wasm32"))]
5pub use std::time::SystemTime;
6
7#[cfg(target_arch = "wasm32")]
8pub use wasm_timer::SystemTime;
9
10/// Time in nanoseconds from [std::time::UNIX_EPOCH].
11///
12/// Used as an ID+Timestamp for an Action`.
13/// Each action will have an unique id. If two actions happen at the same time,
14/// id must be increased by 1 for second action, to ensure uniqueness of id.
15///
16/// u64 is enough to contain time in nanoseconds at most 584 years
17/// after `UNIX_EPOCH` (1970-01-01 00:00:00 UTC).
18///
19/// ```
20/// //           nano     micro  milli  sec    min  hour day  year
21/// assert_eq!(u64::MAX / 1000 / 1000 / 1000 / 60 / 60 / 24 / 365, 584);
22/// ```
23#[cfg_attr(feature = "fuzzing", derive(fuzzcheck::DefaultMutator))]
24#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Clone, Copy)]
25#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
26pub struct Timestamp(u64);
27
28impl Timestamp {
29    pub const ZERO: Self = Self(0);
30
31    #[inline(always)]
32    pub fn new(nanos_from_unix_epoch: u64) -> Self {
33        Self(nanos_from_unix_epoch)
34    }
35
36    #[inline(always)]
37    pub fn global_now() -> Self {
38        Self::new(crate::monotonic_to_time(None))
39    }
40
41    pub fn checked_sub(self, rhs: Timestamp) -> Option<Duration> {
42        self.0.checked_sub(rhs.0).map(Duration::from_nanos)
43    }
44
45    pub fn checked_add(self, other: u64) -> Option<Timestamp> {
46        self.0.checked_add(other).map(Timestamp)
47    }
48}
49
50impl From<Timestamp> for u64 {
51    fn from(t: Timestamp) -> Self {
52        t.0
53    }
54}
55
56impl From<Timestamp> for SystemTime {
57    fn from(value: Timestamp) -> Self {
58        Self::UNIX_EPOCH + Duration::from_nanos(value.into())
59    }
60}
61
62impl std::ops::Add for Timestamp {
63    type Output = Timestamp;
64    #[inline]
65    fn add(self, other: Timestamp) -> Timestamp {
66        Timestamp(self.0 + other.0)
67    }
68}
69
70impl std::ops::Add<u64> for Timestamp {
71    type Output = Timestamp;
72    #[inline]
73    fn add(self, other: u64) -> Timestamp {
74        Timestamp(self.0 + other)
75    }
76}
77
78impl std::ops::Add<Duration> for Timestamp {
79    type Output = Timestamp;
80    #[inline]
81    fn add(self, other: Duration) -> Timestamp {
82        Timestamp(self.0 + other.as_nanos() as u64)
83    }
84}