#![deny(missing_docs)]
#[derive(Clone, PartialEq, Eq, Debug)]
pub enum LogicalExpression<Condition> {
And(Vec<Self>),
Or(Vec<Self>),
Condition(Condition),
}
impl<Condition> LogicalExpression<Condition> {
#[must_use]
pub fn and(mut list: Vec<Self>) -> Self {
if list.len() == 1 {
return unsafe { list.pop().unwrap_unchecked() };
}
Self::And(list)
}
#[must_use]
pub fn or(mut list: Vec<Self>) -> Self {
if list.len() == 1 {
return unsafe { list.pop().unwrap_unchecked() };
}
Self::Or(list)
}
}
impl<Condition: Clone> LogicalExpression<Condition> {
pub fn expand(self) -> Vec<Vec<Condition>> {
match self {
Self::And(groups) => {
let expanded_groups: Vec<_> = groups.into_iter().map(Self::expand).collect();
Self::cartesian_product(expanded_groups)
}
Self::Or(groups) => groups.into_iter().flat_map(Self::expand).collect(),
Self::Condition(condition) => vec![vec![condition]],
}
}
fn cartesian_product(groups: Vec<Vec<Vec<Condition>>>) -> Vec<Vec<Condition>> {
let mut result = vec![Vec::new()];
for group in groups {
let mut new_result = vec![];
for r in &result {
for g in &group {
let mut new_r = r.clone();
new_r.extend(g.clone());
new_result.push(new_r);
}
}
result = new_result;
}
result
}
}
mod parser;
pub use parser::ParseError;