use crate::RoleVariant;
use std::{
marker::PhantomData,
ops::{
BitAnd,
BitAndAssign,
BitOrAssign,
},
};
pub trait BitRoleImpl<T> {
fn empty() -> RoleManager<T>;
fn from_value(value: usize) -> RoleManager<T>;
}
#[derive(Debug)]
pub struct RoleManager<T>(pub usize, pub PhantomData<T>);
impl<T> RoleManager<T>
where
T: RoleVariant,
{
pub fn add_one(&mut self, role: T) -> &mut Self {
self.0.bitor_assign(role.into());
self
}
pub fn add_all(&mut self, roles: Vec<T>) -> &mut Self {
roles.into_iter().for_each(|role| {
self.add_one(role);
});
self
}
pub fn remove_one(&mut self, role: T) -> &mut Self {
self.0.bitand_assign(!role.into());
self
}
pub fn remove_all(&mut self, roles: Vec<T>) -> &mut Self {
roles.into_iter().for_each(|role| {
self.remove_one(role);
});
self
}
pub fn has_one(&self, role: T) -> bool {
self.0.bitand(role.into()) != 0
}
pub fn has_all(&self, roles: Vec<T>) -> bool {
roles
.into_iter()
.all(|role| self.0.bitand(Into::<usize>::into(role)) != 0)
}
pub fn has_any(&self, roles: Vec<T>) -> bool {
roles
.into_iter()
.any(|role| self.0.bitand(Into::<usize>::into(role)) != 0)
}
pub fn not_one(&self, role: T) -> bool {
!self.has_one(role)
}
pub fn not_all(&self, roles: Vec<T>) -> bool {
!self.has_all(roles)
}
pub fn not_any(&self, roles: Vec<T>) -> bool {
!self.has_any(roles)
}
pub fn get_value(&self) -> usize {
self.0
}
}
impl<T> PartialEq<Self> for RoleManager<T> {
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
}
}
impl<T> Eq for RoleManager<T> {}