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