Skip to main content

blockworx/doc_ng/
lamport.rs

1//! The Lamport clock reading: counts causality, not time. Wall time is
2//! display metadata and never load-bearing.
3
4use serde::{Deserialize, Serialize};
5
6#[derive(
7    Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default, Serialize, Deserialize,
8)]
9pub struct Lamport(u64);
10
11impl Lamport {
12    pub const ZERO: Lamport = Lamport(0);
13
14    pub const fn new(n: u64) -> Self {
15        Self(n)
16    }
17
18    pub const fn get(self) -> u64 {
19        self.0
20    }
21
22    /// Saturating: a replica that somehow reached `u64::MAX` must not wrap
23    /// back into the distant past.
24    #[must_use]
25    pub const fn next(self) -> Self {
26        Self(self.0.saturating_add(1))
27    }
28}
29
30#[cfg(test)]
31mod tests {
32    use super::*;
33
34    #[test]
35    fn next_advances_and_orders() {
36        let one = Lamport::ZERO.next();
37        assert_eq!(one, Lamport::new(1));
38        assert!(Lamport::ZERO < one);
39    }
40
41    #[test]
42    fn next_saturates_instead_of_wrapping() {
43        let max = Lamport::new(u64::MAX);
44        assert_eq!(max.next(), max);
45    }
46}