1#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
7#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8#[repr(transparent)]
9pub struct SegmentFlags(u16);
10
11impl SegmentFlags {
12 pub const COMPRESSED: u16 = 0x0001;
14 pub const ENCRYPTED: u16 = 0x0002;
16 pub const SIGNED: u16 = 0x0004;
18 pub const SEALED: u16 = 0x0008;
20 pub const PARTIAL: u16 = 0x0010;
22 pub const TOMBSTONE: u16 = 0x0020;
24 pub const HOT: u16 = 0x0040;
26 pub const OVERLAY: u16 = 0x0080;
28 pub const SNAPSHOT: u16 = 0x0100;
30 pub const CHECKPOINT: u16 = 0x0200;
32 pub const ATTESTED: u16 = 0x0400;
34 pub const HAS_LINEAGE: u16 = 0x0800;
36
37 const KNOWN_MASK: u16 = 0x0FFF;
39
40 #[inline]
42 pub const fn empty() -> Self {
43 Self(0)
44 }
45
46 #[inline]
48 pub const fn from_raw(raw: u16) -> Self {
49 Self(raw & Self::KNOWN_MASK)
50 }
51
52 #[inline]
54 pub const fn bits(self) -> u16 {
55 self.0
56 }
57
58 #[inline]
60 pub const fn contains(self, flag: u16) -> bool {
61 self.0 & flag == flag
62 }
63
64 #[inline]
66 pub const fn with(self, flag: u16) -> Self {
67 Self(self.0 | (flag & Self::KNOWN_MASK))
68 }
69
70 #[inline]
72 pub const fn without(self, flag: u16) -> Self {
73 Self(self.0 & !flag)
74 }
75
76 #[inline]
78 pub const fn is_empty(self) -> bool {
79 self.0 == 0
80 }
81}
82
83#[cfg(test)]
84mod tests {
85 use super::*;
86
87 #[test]
88 fn empty_flags() {
89 let f = SegmentFlags::empty();
90 assert!(f.is_empty());
91 assert_eq!(f.bits(), 0);
92 }
93
94 #[test]
95 fn set_and_check_flags() {
96 let f = SegmentFlags::empty()
97 .with(SegmentFlags::COMPRESSED)
98 .with(SegmentFlags::SEALED);
99 assert!(f.contains(SegmentFlags::COMPRESSED));
100 assert!(f.contains(SegmentFlags::SEALED));
101 assert!(!f.contains(SegmentFlags::ENCRYPTED));
102 }
103
104 #[test]
105 fn clear_flag() {
106 let f = SegmentFlags::empty()
107 .with(SegmentFlags::COMPRESSED)
108 .with(SegmentFlags::SIGNED)
109 .without(SegmentFlags::COMPRESSED);
110 assert!(!f.contains(SegmentFlags::COMPRESSED));
111 assert!(f.contains(SegmentFlags::SIGNED));
112 }
113
114 #[test]
115 fn reserved_bits_masked() {
116 let f = SegmentFlags::from_raw(0xFFFF);
117 assert_eq!(f.bits(), 0x0FFF);
118 }
119
120 #[test]
121 fn all_known_flags() {
122 let all = SegmentFlags::empty()
123 .with(SegmentFlags::COMPRESSED)
124 .with(SegmentFlags::ENCRYPTED)
125 .with(SegmentFlags::SIGNED)
126 .with(SegmentFlags::SEALED)
127 .with(SegmentFlags::PARTIAL)
128 .with(SegmentFlags::TOMBSTONE)
129 .with(SegmentFlags::HOT)
130 .with(SegmentFlags::OVERLAY)
131 .with(SegmentFlags::SNAPSHOT)
132 .with(SegmentFlags::CHECKPOINT)
133 .with(SegmentFlags::ATTESTED)
134 .with(SegmentFlags::HAS_LINEAGE);
135 assert_eq!(all.bits(), 0x0FFF);
136 }
137}