use bitflags::bitflags;
bitflags! {
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default, serde::Serialize, serde::Deserialize)]
pub struct CapabilityMask: u64 {
const SYSTEM = 1 << 0;
const ADMIN_UNLOAD = 1 << 1;
const OBSERVER_REGISTER = 1 << 2;
const INTROSPECT = 1 << 3;
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn caps_combine_via_bitor() {
let c = CapabilityMask::SYSTEM | CapabilityMask::ADMIN_UNLOAD;
assert!(c.contains(CapabilityMask::SYSTEM));
assert!(c.contains(CapabilityMask::ADMIN_UNLOAD));
assert!(!c.contains(CapabilityMask::INTROSPECT));
assert!(!c.contains(CapabilityMask::OBSERVER_REGISTER));
}
#[test]
fn caps_default_is_empty() {
let empty = CapabilityMask::default();
assert!(empty.is_empty());
assert!(!empty.contains(CapabilityMask::SYSTEM));
}
#[test]
fn caps_all_reserved_bits_have_distinct_positions() {
let all = CapabilityMask::SYSTEM
| CapabilityMask::ADMIN_UNLOAD
| CapabilityMask::OBSERVER_REGISTER
| CapabilityMask::INTROSPECT;
assert_eq!(all.bits(), 0b1111);
}
#[test]
fn caps_intersection_contains() {
let a = CapabilityMask::SYSTEM | CapabilityMask::INTROSPECT;
let b = CapabilityMask::INTROSPECT | CapabilityMask::OBSERVER_REGISTER;
assert_eq!(a & b, CapabilityMask::INTROSPECT);
}
#[test]
fn caps_subset_relationship() {
let full = CapabilityMask::SYSTEM | CapabilityMask::ADMIN_UNLOAD;
let partial = CapabilityMask::SYSTEM;
assert!(full.contains(partial));
assert!(!partial.contains(full));
}
}