pub type Perm = (usize, u8);
pub trait Perms {
type Error;
fn perm_get(&self, perm: Perm) -> bool;
fn perm_set(&mut self, perm: Perm, value: bool);
fn perm_any(&self) -> bool;
fn perm_check(&self, perm: Perm) -> Result<(), Self::Error>;
fn perm_check_many(&self, perms: &[Perm]) -> Result<(), Self::Error> {
for p in perms {
self.perm_check(*p)?;
}
Ok(())
}
fn perm_test(&self, perm: Perm) -> bool {
self.perm_check(perm).is_ok()
}
}
impl Perms for [u8] {
type Error = ();
fn perm_check(&self, perm: Perm) -> Result<(), Self::Error> {
if self.perm_get(perm) { Ok(()) } else { Err(()) }
}
fn perm_any(&self) -> bool {
self.iter().any(|v| *v != 0)
}
fn perm_get(&self, (byte, bit): Perm) -> bool {
if self.len() <= byte {
return false;
}
let n = self[byte];
let f = 1 << bit;
(n & f) == f
}
fn perm_set(&mut self, (byte, bit): Perm, value: bool) {
if self.len() <= byte {
return;
}
let f = 1 << bit;
if value {
self[byte] |= f;
} else {
self[byte] &= !f;
}
}
}
#[cfg(test)]
mod tests {
use super::Perms;
crate::perms!(A, _P, _P, _P, _P, _P, _P, _P, _P, C);
#[test]
fn perms() {
let mut perms = [0u8; 3];
assert_eq!(perms, [0, 0, 0]);
assert!(!perms.perm_get(A));
perms.perm_set(A, true);
assert!(perms.perm_get(A));
assert_eq!(perms, [1, 0, 0]);
perms.perm_set(A, false);
assert!(!perms.perm_get(C));
perms.perm_set(C, true);
assert!(perms.perm_get(C));
assert_eq!(perms, [0, 2, 0]);
}
}