Skip to main content

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))]
26#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
27pub struct Timestamp(u64);
28
29impl Timestamp {
30    pub const ZERO: Self = Self(0);
31
32    #[inline(always)]
33    pub fn new(nanos_from_unix_epoch: u64) -> Self {
34        Self(nanos_from_unix_epoch)
35    }
36
37    #[inline(always)]
38    pub fn global_now() -> Self {
39        Self::new(crate::monotonic_to_time(None))
40    }
41
42    pub fn checked_sub(self, rhs: Timestamp) -> Option<Duration> {
43        self.0.checked_sub(rhs.0).map(Duration::from_nanos)
44    }
45
46    pub fn checked_add(self, other: u64) -> Option<Timestamp> {
47        self.0.checked_add(other).map(Timestamp)
48    }
49}
50
51impl From<Timestamp> for u64 {
52    fn from(t: Timestamp) -> Self {
53        t.0
54    }
55}
56
57impl From<Timestamp> for SystemTime {
58    fn from(value: Timestamp) -> Self {
59        Self::UNIX_EPOCH + Duration::from_nanos(value.into())
60    }
61}
62
63impl std::ops::Add for Timestamp {
64    type Output = Timestamp;
65    #[inline]
66    fn add(self, other: Timestamp) -> Timestamp {
67        Timestamp(self.0 + other.0)
68    }
69}
70
71impl std::ops::Add<u64> for Timestamp {
72    type Output = Timestamp;
73    #[inline]
74    fn add(self, other: u64) -> Timestamp {
75        Timestamp(self.0 + other)
76    }
77}
78
79impl std::ops::Add<Duration> for Timestamp {
80    type Output = Timestamp;
81    #[inline]
82    fn add(self, other: Duration) -> Timestamp {
83        Timestamp(self.0 + other.as_nanos() as u64)
84    }
85}