redux/action/
action_id.rs

1use std::time::Duration;
2
3use crate::Timestamp;
4
5/// Time in nanoseconds from [std::time::UNIX_EPOCH].
6///
7/// Each action will have unique id. If two actions happen at the same time,
8/// id must be increased by 1 for second action, to ensure uniqueness of id.
9///
10/// u64 is enough to contain time in nanoseconds at most 584 years
11/// after `UNIX_EPOCH` (1970-01-01 00:00:00 UTC).
12///
13/// ```
14/// //           nano     micro  milli  sec    min  hour day  year
15/// assert_eq!(u64::MAX / 1000 / 1000 / 1000 / 60 / 60 / 24 / 365, 584);
16/// ```
17#[cfg_attr(feature = "fuzzing", derive(fuzzcheck::DefaultMutator))]
18#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Clone, Copy)]
19#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
20pub struct ActionId(Timestamp);
21
22impl ActionId {
23    pub const ZERO: Self = Self(Timestamp::ZERO);
24
25    /// Caller must make sure such action actually exists!
26    #[inline(always)]
27    pub fn new_unchecked(value: u64) -> Self {
28        Self(Timestamp::new(value))
29    }
30
31    #[allow(unused)]
32    #[inline(always)]
33    pub(crate) fn next(&self, time_passed: u64) -> Self {
34        Self(self.0 + time_passed.max(1))
35    }
36
37    pub fn duration_since(&self, other: ActionId) -> Duration {
38        let d = self.0.checked_sub(other.0);
39        debug_assert!(d.is_some());
40        d.unwrap_or(Duration::ZERO)
41    }
42}
43
44impl From<ActionId> for Timestamp {
45    #[inline(always)]
46    fn from(id: ActionId) -> Self {
47        id.0
48    }
49}
50
51impl From<ActionId> for u64 {
52    #[inline(always)]
53    fn from(id: ActionId) -> Self {
54        id.0.into()
55    }
56}