1use std::fmt;
7
8use serde::{Deserialize, Serialize};
9
10#[derive(
15 Debug,
16 Clone,
17 Copy,
18 PartialEq,
19 Eq,
20 PartialOrd,
21 Ord,
22 Hash,
23 Serialize,
24 Deserialize,
25 rkyv::Archive,
26 rkyv::Serialize,
27 rkyv::Deserialize,
28 zerompk::ToMessagePack,
29 zerompk::FromMessagePack,
30)]
31pub struct Lsn(u64);
32
33impl Lsn {
34 pub const ZERO: Lsn = Lsn(0);
35
36 pub const fn new(value: u64) -> Self {
37 Self(value)
38 }
39
40 pub const fn as_u64(self) -> u64 {
41 self.0
42 }
43
44 pub const fn next(self) -> Self {
46 Self(self.0 + 1)
47 }
48
49 pub const fn is_ahead_of(self, other: Self) -> bool {
51 self.0 > other.0
52 }
53}
54
55impl fmt::Display for Lsn {
56 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57 write!(f, "lsn:{}", self.0)
58 }
59}
60
61#[cfg(test)]
62mod tests {
63 use super::*;
64
65 #[test]
66 fn lsn_ordering() {
67 let a = Lsn::new(1);
68 let b = Lsn::new(2);
69 assert!(a < b);
70 assert_eq!(a.next(), b);
71 assert!(b.is_ahead_of(a));
72 assert!(!a.is_ahead_of(b));
73 }
74
75 #[test]
76 fn lsn_display() {
77 assert_eq!(Lsn::new(42).to_string(), "lsn:42");
78 }
79
80 #[test]
81 fn lsn_zero() {
82 assert_eq!(Lsn::ZERO.as_u64(), 0);
83 }
84}