use smol_str::SmolStr;
use std::collections::HashSet;
use cedar_policy_core::ast::{Expr, ExprShapeOnly};
#[derive(Eq, PartialEq, Debug, Clone, Default)]
pub struct CapabilitySet<'a>(HashSet<Capability<'a>>);
impl<'a> CapabilitySet<'a> {
pub fn new() -> Self {
CapabilitySet(HashSet::new())
}
pub fn singleton(e: Capability<'a>) -> Self {
let mut set = Self::new();
set.0.insert(e);
set
}
pub fn union(&self, other: &Self) -> Self {
CapabilitySet(self.0.union(&other.0).cloned().collect())
}
pub fn intersect(&self, other: &Self) -> Self {
CapabilitySet(self.0.intersection(&other.0).cloned().collect())
}
pub fn contains(&self, e: &Capability<'_>) -> bool {
self.0.contains(e)
}
}
#[derive(Hash, Eq, PartialEq, Debug, Clone)]
pub struct Capability<'a> {
on_expr: ExprShapeOnly<'a, ()>,
attribute_or_tag: ExprShapeOnly<'a, ()>,
kind: CapabilityKind,
}
#[derive(Hash, Eq, PartialEq, Debug, Clone, Copy)]
enum CapabilityKind {
Attribute,
Tag,
}
impl<'a> Capability<'a> {
pub fn new_attribute(on_expr: &'a Expr<()>, attribute: SmolStr) -> Self {
Self {
on_expr: ExprShapeOnly::new_from_borrowed(on_expr),
attribute_or_tag: ExprShapeOnly::new_from_owned(Expr::val(attribute)),
kind: CapabilityKind::Attribute,
}
}
pub fn new_borrowed_tag(on_expr: &'a Expr<()>, tag: &'a Expr<()>) -> Self {
Self {
on_expr: ExprShapeOnly::new_from_borrowed(on_expr),
attribute_or_tag: ExprShapeOnly::new_from_borrowed(tag),
kind: CapabilityKind::Tag,
}
}
pub fn new_owned_tag(on_expr: &'a Expr<()>, tag: Expr<()>) -> Self {
Self {
on_expr: ExprShapeOnly::new_from_borrowed(on_expr),
attribute_or_tag: ExprShapeOnly::new_from_owned(tag),
kind: CapabilityKind::Tag,
}
}
}