use super::composite::PermissionSet;
use crate::algebra::{JoinSemilattice, MeetSemilattice, Monoid, Semigroup};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
pub type DenialSet = PermissionSet;
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Default)]
pub struct GrantDenialPair {
pub grants: PermissionSet,
pub denials: DenialSet,
}
impl GrantDenialPair {
pub fn new(grants: PermissionSet, denials: DenialSet) -> Self {
Self { grants, denials }
}
pub fn effective_permissions(&self) -> PermissionSet {
self.grants.difference(&self.denials)
}
pub fn has_permission(&self, perm: &super::atomic::AtomicPermission) -> bool {
self.grants.contains(perm) && !self.denials.contains(perm)
}
pub fn empty() -> Self {
Self {
grants: PermissionSet::identity(),
denials: DenialSet::identity(),
}
}
}
impl Semigroup for GrantDenialPair {
fn combine(self, other: Self) -> Self {
Self {
grants: self.grants.combine(other.grants),
denials: self.denials.combine(other.denials),
}
}
}
impl Monoid for GrantDenialPair {
fn identity() -> Self {
Self::empty()
}
}
impl PartialOrd for GrantDenialPair {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
self.effective_permissions()
.partial_cmp(&other.effective_permissions())
}
}
impl MeetSemilattice for GrantDenialPair {
fn meet(self, other: Self) -> Self {
Self {
grants: self.grants.meet(other.grants),
denials: self.denials.join(other.denials), }
}
}
impl JoinSemilattice for GrantDenialPair {
fn join(self, other: Self) -> Self {
Self {
grants: self.grants.join(other.grants),
denials: self.denials.meet(other.denials), }
}
}