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)]
29pub struct Lsn(u64);
30
31impl Lsn {
32 pub const ZERO: Lsn = Lsn(0);
33
34 pub const fn new(value: u64) -> Self {
35 Self(value)
36 }
37
38 pub const fn as_u64(self) -> u64 {
39 self.0
40 }
41
42 pub const fn next(self) -> Self {
44 Self(self.0 + 1)
45 }
46
47 pub const fn is_ahead_of(self, other: Self) -> bool {
49 self.0 > other.0
50 }
51}
52
53impl fmt::Display for Lsn {
54 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55 write!(f, "lsn:{}", self.0)
56 }
57}
58
59#[cfg(test)]
60mod tests {
61 use super::*;
62
63 #[test]
64 fn lsn_ordering() {
65 let a = Lsn::new(1);
66 let b = Lsn::new(2);
67 assert!(a < b);
68 assert_eq!(a.next(), b);
69 assert!(b.is_ahead_of(a));
70 assert!(!a.is_ahead_of(b));
71 }
72
73 #[test]
74 fn lsn_display() {
75 assert_eq!(Lsn::new(42).to_string(), "lsn:42");
76 }
77
78 #[test]
79 fn lsn_zero() {
80 assert_eq!(Lsn::ZERO.as_u64(), 0);
81 }
82}