use crate::CriteriumChain;
#[derive(Debug, Clone, Copy)]
pub struct LogicPath {
depth: usize,
is_plain_and: bool,
is_plain_or: bool,
is_inverted: bool,
is_branch_inverted: bool,
}
impl LogicPath {
pub fn new_root() -> Self {
LogicPath {
depth: 0,
is_plain_and: false,
is_plain_or: true,
is_inverted: false,
is_branch_inverted: false,
}
}
pub fn depth(&self) -> usize {
self.depth
}
pub fn is_root(&self) -> bool {
self.depth == 0
}
pub fn is_plain_and(&self) -> bool {
self.is_plain_and
}
pub fn is_plain_or(&self) -> bool {
self.is_plain_or
}
pub fn is_excluding(&self) -> bool {
self.is_inverted
}
pub fn is_branch_inverted(&self) -> bool {
self.is_branch_inverted
}
pub fn and(&self) -> Self {
Self {
is_plain_or: false,
is_plain_and: self.is_plain_and || self.is_root(),
is_inverted: self.is_inverted,
is_branch_inverted: false,
depth: self.depth + 1,
}
}
pub fn or(&self) -> Self {
Self {
is_plain_and: false,
is_plain_or: self.is_plain_or || self.is_root(),
is_inverted: self.is_inverted,
is_branch_inverted: false,
depth: self.depth + 1,
}
}
pub fn not(&self) -> Self {
Self {
is_plain_and: false,
is_plain_or: false,
is_inverted: !self.is_inverted,
is_branch_inverted: !self.is_branch_inverted,
depth: self.depth + 1,
}
}
pub fn traverse<T>(&self, chain: &CriteriumChain<T>) -> Self {
match chain {
CriteriumChain::And(_) => self.and(),
CriteriumChain::Or(_) => self.or(),
CriteriumChain::NotChain(_) | CriteriumChain::Not(_) => self.not(),
CriteriumChain::MatchAlways
| CriteriumChain::MatchNever
| CriteriumChain::Match(_)
| CriteriumChain::WithLikelihood { .. } => *self,
}
}
}