Skip to main content

ps_uuid/state/methods/
next.rs

1use std::time::{Duration, SystemTime};
2
3use crate::State;
4
5const FIDELITY: Duration = Duration::from_nanos(100);
6
7impl State {
8    /// This method returns the next [`UUID`](crate::UUID)'s timestamp and clock sequence.
9    ///
10    /// 1. Increments this [`State`]'s timestamp by 100 ns,
11    /// 2. compares this with the timestamp provided,
12    /// 3. if the provided timestamp is greater or equal, the clock sequence is incremented,
13    /// 4. the timestamp and clock sequence are returned.
14    ///
15    /// # Usage
16    ///
17    /// ```
18    /// use ps_uuid::STATE;
19    /// use std::time::SystemTime;
20    ///
21    /// let (timestamp, clock_seq) = STATE.lock().next(SystemTime::now());
22    /// ```
23    pub fn next(&mut self, timestamp: SystemTime) -> (SystemTime, u16) {
24        if timestamp <= self.last_ts + FIDELITY {
25            self.seq = (self.seq.wrapping_add(1)) & 0x3FFF;
26        }
27
28        self.last_ts = timestamp;
29
30        (timestamp, self.seq)
31    }
32}
33
34#[cfg(test)]
35mod tests {
36    use std::time::SystemTime;
37
38    use crate::STATE;
39
40    #[test]
41    fn always_increments() {
42        let mut guard = STATE.lock_arc();
43
44        let mut previous = guard.next(SystemTime::now());
45
46        for _ in 0..99999 {
47            let next = guard.next(SystemTime::now());
48
49            assert!(
50                next > previous,
51                "Next timestamp or sequence number must be greater."
52            );
53
54            previous = next;
55        }
56
57        drop(guard);
58    }
59}