#[derive(Debug, Clone, PartialEq)]
pub enum BooleanExpr {
RegionRef(String),
Union(Box<BooleanExpr>, Box<BooleanExpr>),
#[cfg(feature = "boolean_ops")]
Difference(Box<BooleanExpr>, Box<BooleanExpr>),
#[cfg(feature = "boolean_ops")]
Intersection(Box<BooleanExpr>, Box<BooleanExpr>),
#[cfg(feature = "boolean_ops")]
Xor(Box<BooleanExpr>, Box<BooleanExpr>),
}
impl BooleanExpr {
pub fn union(left: BooleanExpr, right: BooleanExpr) -> Self {
BooleanExpr::Union(Box::new(left), Box::new(right))
}
#[cfg(feature = "boolean_ops")]
pub fn difference(left: BooleanExpr, right: BooleanExpr) -> Self {
BooleanExpr::Difference(Box::new(left), Box::new(right))
}
#[cfg(feature = "boolean_ops")]
pub fn intersection(left: BooleanExpr, right: BooleanExpr) -> Self {
BooleanExpr::Intersection(Box::new(left), Box::new(right))
}
#[cfg(feature = "boolean_ops")]
pub fn xor(left: BooleanExpr, right: BooleanExpr) -> Self {
BooleanExpr::Xor(Box::new(left), Box::new(right))
}
pub fn region_ref(name: impl Into<String>) -> Self {
BooleanExpr::RegionRef(name.into())
}
pub fn region_refs(&self) -> Vec<&str> {
let mut refs = Vec::new();
self.collect_region_refs(&mut refs);
refs
}
fn collect_region_refs<'a>(&'a self, refs: &mut Vec<&'a str>) {
match self {
BooleanExpr::RegionRef(name) => refs.push(name),
BooleanExpr::Union(left, right) => {
left.collect_region_refs(refs);
right.collect_region_refs(refs);
}
#[cfg(feature = "boolean_ops")]
BooleanExpr::Difference(left, right)
| BooleanExpr::Intersection(left, right)
| BooleanExpr::Xor(left, right) => {
left.collect_region_refs(refs);
right.collect_region_refs(refs);
}
}
}
}
impl std::fmt::Display for BooleanExpr {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
BooleanExpr::RegionRef(name) => write!(f, "{}", name),
BooleanExpr::Union(left, right) => write!(f, "({} + {})", left, right),
#[cfg(feature = "boolean_ops")]
BooleanExpr::Difference(left, right) => write!(f, "({} - {})", left, right),
#[cfg(feature = "boolean_ops")]
BooleanExpr::Intersection(left, right) => write!(f, "({} & {})", left, right),
#[cfg(feature = "boolean_ops")]
BooleanExpr::Xor(left, right) => write!(f, "({} ^ {})", left, right),
}
}
}