kekbit_core/
tick.rs

1//! Time granularity units used in kekbit.
2use std::time::Duration;
3use std::time::{SystemTime, UNIX_EPOCH};
4
5///A TickUnit represents a specific time duration but does not maintain time information, it only helps define the time granularity
6///required to used in various contexts by all kekbit components which *share a given channel*.
7///For each channel it's TickUnit will be spcified at creation and will *never be changed*
8#[derive(PartialEq, Eq, Debug, Copy, Clone)]
9pub enum TickUnit {
10    ///TickUnit representing one thousandth of a microsecond.
11    Nanos,
12    ///TickUnit representing one thousandth of a millisecond.
13    Micros,
14    ///TickUnit representing one thousandth of a second.
15    Millis,
16    ///TickUnit representing one second.
17    Secs,
18}
19
20impl TickUnit {
21    ///Returns the unique u8 id assigned to every TickUnit. This id it's used for serialization it would never change.
22    ///
23    /// # Examples
24    /// ```
25    /// use kekbit_core::tick::TickUnit::*;
26    ///
27    /// assert_eq!(Nanos.id(), 9);
28    /// assert_eq!(Micros.id(), 6);
29    /// assert_eq!(Millis.id(), 3);
30    /// assert_eq!(Secs.id(), 0);
31    /// ```
32    #[inline]
33    pub fn id(self) -> u8 {
34        match self {
35            TickUnit::Nanos => 9,
36            TickUnit::Micros => 6,
37            TickUnit::Millis => 3,
38            TickUnit::Secs => 0,
39        }
40    }
41
42    /// Returns the tick unit with the given id
43    ///
44    /// # Arguments
45    ///
46    /// * `id` - The identifier of the tick unit as u8. In the curent kekbit version it must be **0, 3, 6 or 9**
47    ///
48    /// # Panics
49    ///
50    /// If the specified id has no tick unit attached
51    ///
52    #[inline]
53    pub fn from_id(id: u8) -> TickUnit {
54        match id {
55            9 => TickUnit::Nanos,
56            6 => TickUnit::Micros,
57            3 => TickUnit::Millis,
58            0 => TickUnit::Secs,
59            _ => panic!("Unknown time unit id {}", id),
60        }
61    }
62    /// Returns the total number of tick units contained by this `Duration` as a u64.
63    /// If the tiemstamp size is longer than 64 bits, it will be truncated to the lower 64 bits
64    ///
65    /// # Examples
66    ///
67    /// ```
68    /// use std::time::Duration;
69    /// use kekbit_core::tick::TickUnit::*;
70    ///
71    ///let duration = Duration::new(1, 500_000_000); //1 sec and a half
72    ///assert_eq!(Nanos.convert(duration), 1_500_000_000);
73    ///assert_eq!(Micros.convert(duration), 1_500_000);
74    ///assert_eq!(Millis.convert(duration), 1_500);
75    ///assert_eq!(Secs.convert(duration), 1);
76    /// ```
77    #[inline]
78    pub fn convert(self, duration: Duration) -> u64 {
79        match self {
80            TickUnit::Nanos => duration.as_nanos() as u64,
81            TickUnit::Micros => duration.as_micros() as u64,
82            TickUnit::Millis => duration.as_millis() as u64,
83            TickUnit::Secs => duration.as_secs(),
84        }
85    }
86    ///Returns the difference, measured in the current tick unit, between the current time and midnight, January 1, 1970 UTC.
87    ///
88    /// # Examples
89    ///  ```
90    /// use kekbit_core::tick::TickUnit::*;
91    ///
92    /// println!("{}ms since January 1, 1970 UTC", Millis.nix_time());
93    /// ```
94    #[inline]
95    pub fn nix_time(self) -> u64 {
96        self.convert(SystemTime::now().duration_since(UNIX_EPOCH).unwrap())
97    }
98}
99
100#[cfg(test)]
101mod tests {
102    use super::TickUnit::*;
103    use super::*;
104    use std::time::Duration;
105    #[test]
106    fn check_ids_symetry() {
107        assert_eq!(Nanos.id(), TickUnit::from_id(Nanos.id()).id());
108        assert_eq!(Micros.id(), TickUnit::from_id(Micros.id()).id());
109        assert_eq!(Millis.id(), TickUnit::from_id(Millis.id()).id());
110        assert_eq!(Secs.id(), TickUnit::from_id(Secs.id()).id());
111    }
112
113    #[test]
114    #[should_panic]
115    fn check_wrong_id() {
116        TickUnit::from_id(123);
117    }
118
119    #[test]
120    fn test_coversion() {
121        let duration = Duration::new(1, 500_000_000); //1 sec and a half
122        assert_eq!(Nanos.convert(duration), 1_500_000_000);
123        assert_eq!(Micros.convert(duration), 1_500_000);
124        assert_eq!(Millis.convert(duration), 1_500);
125        assert_eq!(Secs.convert(duration), 1);
126    }
127
128    #[test]
129    fn check_ids() {
130        assert_eq!(Nanos.id(), 9);
131        assert_eq!(Micros.id(), 6);
132        assert_eq!(Millis.id(), 3);
133        assert_eq!(Secs.id(), 0);
134    }
135
136    #[test]
137    fn check_nix_time() {
138        let t1 = Nanos.nix_time();
139        let t2 = Nanos.nix_time();
140        assert!(t1 <= t2);
141    }
142}