use std::fmt;
use super::error::*;
#[derive(Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord)]
#[repr(transparent)]
pub struct Flags {
pub(crate) bits: u32,
}
impl Flags {
pub const RESERVED_MASK: u32 = 0b1111_1111_1111_1111_0000_0000_0000_0000;
pub const BYTES: usize = 4;
pub const COMPRESSED_FLAG: u32 = 0b_1000_0000_0000_0000_0000_0000_0000_0000;
pub const LZ4_COMPRESSED: u32 = 0b_0100_0000_0000_0000_0000_0000_0000_0000;
pub const SNAPPY_COMPRESSED: u32 = 0b_0010_0000_0000_0000_0000_0000_0000_0000;
pub const BROTLI_COMPRESSED: u32 = 0b_0001_0000_0000_0000_0000_0000_0000_0000;
pub const SIGNED_FLAG: u32 = 0b_0000_1000_0000_0000_0000_0000_0000_0000;
pub const ENCRYPTED_FLAG: u32 = 0b_0000_0010_0000_0000_0000_0000_0000_0000;
#[inline(always)]
pub const fn from_bits(bits: u32) -> Self {
Flags { bits }
}
#[inline(always)]
pub const fn bits(&self) -> u32 {
self.bits
}
#[inline(always)]
pub const fn new() -> Self {
Flags { bits: 0 }
}
pub const fn set(&mut self, bit: u32, toggle: bool) -> InternalResult<u32> {
if (Flags::RESERVED_MASK & bit) != 0 {
return Err(InternalError::RestrictedFlagAccessError);
} else {
self.force_set(bit, toggle)
}
Ok(self.bits)
}
pub(crate) const fn force_set(&mut self, mask: u32, toggle: bool) {
if toggle {
self.bits |= mask;
} else {
self.bits &= !mask;
}
}
#[inline(always)]
pub const fn contains(&self, bit: u32) -> bool {
(self.bits & bit) != 0
}
}
#[rustfmt::skip]
impl fmt::Display for Flags {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let compressed = if self.contains(Flags::COMPRESSED_FLAG) { 'C' } else { '-' };
let signed = if self.contains(Flags::SIGNED_FLAG) { 'S' } else { '-' };
let encrypted = if self.contains(Flags::ENCRYPTED_FLAG) { 'E' } else { '-' };
write!(f, "Flags[{}{}{}] = {:>8X}", compressed, encrypted, signed, self.bits)
}
}
#[rustfmt::skip]
impl fmt::Debug for Flags {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let compressed = if self.contains(Flags::COMPRESSED_FLAG) { 'C' } else { '-' };
let signed = if self.contains(Flags::SIGNED_FLAG) { 'S' } else { '-' };
let encrypted = if self.contains(Flags::ENCRYPTED_FLAG) { 'E' } else { '-' };
write!(
f,
"Flags[{}{}{}]: <{}u32 : {:#032b}>",
compressed, encrypted, signed, self.bits, self.bits
)
}
}