#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(transparent)]
pub struct SegmentFlags(u16);
impl SegmentFlags {
pub const COMPRESSED: u16 = 0x0001;
pub const ENCRYPTED: u16 = 0x0002;
pub const SIGNED: u16 = 0x0004;
pub const SEALED: u16 = 0x0008;
pub const PARTIAL: u16 = 0x0010;
pub const TOMBSTONE: u16 = 0x0020;
pub const HOT: u16 = 0x0040;
pub const OVERLAY: u16 = 0x0080;
pub const SNAPSHOT: u16 = 0x0100;
pub const CHECKPOINT: u16 = 0x0200;
pub const ATTESTED: u16 = 0x0400;
pub const HAS_LINEAGE: u16 = 0x0800;
const KNOWN_MASK: u16 = 0x0FFF;
#[inline]
pub const fn empty() -> Self {
Self(0)
}
#[inline]
pub const fn from_raw(raw: u16) -> Self {
Self(raw & Self::KNOWN_MASK)
}
#[inline]
pub const fn bits(self) -> u16 {
self.0
}
#[inline]
pub const fn contains(self, flag: u16) -> bool {
self.0 & flag == flag
}
#[inline]
pub const fn with(self, flag: u16) -> Self {
Self(self.0 | (flag & Self::KNOWN_MASK))
}
#[inline]
pub const fn without(self, flag: u16) -> Self {
Self(self.0 & !flag)
}
#[inline]
pub const fn is_empty(self) -> bool {
self.0 == 0
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn empty_flags() {
let f = SegmentFlags::empty();
assert!(f.is_empty());
assert_eq!(f.bits(), 0);
}
#[test]
fn set_and_check_flags() {
let f = SegmentFlags::empty()
.with(SegmentFlags::COMPRESSED)
.with(SegmentFlags::SEALED);
assert!(f.contains(SegmentFlags::COMPRESSED));
assert!(f.contains(SegmentFlags::SEALED));
assert!(!f.contains(SegmentFlags::ENCRYPTED));
}
#[test]
fn clear_flag() {
let f = SegmentFlags::empty()
.with(SegmentFlags::COMPRESSED)
.with(SegmentFlags::SIGNED)
.without(SegmentFlags::COMPRESSED);
assert!(!f.contains(SegmentFlags::COMPRESSED));
assert!(f.contains(SegmentFlags::SIGNED));
}
#[test]
fn reserved_bits_masked() {
let f = SegmentFlags::from_raw(0xFFFF);
assert_eq!(f.bits(), 0x0FFF);
}
#[test]
fn all_known_flags() {
let all = SegmentFlags::empty()
.with(SegmentFlags::COMPRESSED)
.with(SegmentFlags::ENCRYPTED)
.with(SegmentFlags::SIGNED)
.with(SegmentFlags::SEALED)
.with(SegmentFlags::PARTIAL)
.with(SegmentFlags::TOMBSTONE)
.with(SegmentFlags::HOT)
.with(SegmentFlags::OVERLAY)
.with(SegmentFlags::SNAPSHOT)
.with(SegmentFlags::CHECKPOINT)
.with(SegmentFlags::ATTESTED)
.with(SegmentFlags::HAS_LINEAGE);
assert_eq!(all.bits(), 0x0FFF);
}
}