use std::collections::BTreeSet;
use super::symbols::VariableSymbol;
use super::term::Term;
#[derive(Clone, Debug, Eq, Hash, PartialEq, serde::Serialize, serde::Deserialize)]
#[serde(deny_unknown_fields)]
pub enum BuiltinFilter {
Eq(Term, Term),
Ne(Term, Term),
Lt(Term, Term),
Le(Term, Term),
Gt(Term, Term),
Ge(Term, Term),
StrStarts(Term, Term),
StrEnds(Term, Term),
Contains(Term, Term),
RegexMatch {
value: Term,
pattern: Term,
flags: Option<Term>,
},
IsIri(Term),
IsLiteral(Term),
IsBlank(Term),
IsNumeric(Term),
LangMatches(Term, Term),
And(Box<BuiltinFilter>, Box<BuiltinFilter>),
Or(Box<BuiltinFilter>, Box<BuiltinFilter>),
Not(Box<BuiltinFilter>),
}
impl BuiltinFilter {
#[must_use]
pub fn variables(&self) -> BTreeSet<VariableSymbol> {
let mut out = BTreeSet::new();
self.collect_variables(&mut out);
out
}
fn collect_variables(&self, out: &mut BTreeSet<VariableSymbol>) {
match self {
Self::Eq(a, b)
| Self::Ne(a, b)
| Self::Lt(a, b)
| Self::Le(a, b)
| Self::Gt(a, b)
| Self::Ge(a, b)
| Self::StrStarts(a, b)
| Self::StrEnds(a, b)
| Self::Contains(a, b) => {
insert_variable(a, out);
insert_variable(b, out);
}
Self::RegexMatch {
value,
pattern,
flags,
} => {
insert_variable(value, out);
insert_variable(pattern, out);
if let Some(flags) = flags {
insert_variable(flags, out);
}
}
Self::IsIri(t) | Self::IsLiteral(t) | Self::IsBlank(t) | Self::IsNumeric(t) => {
insert_variable(t, out);
}
Self::LangMatches(tag, range) => {
insert_variable(tag, out);
insert_variable(range, out);
}
Self::And(lhs, rhs) | Self::Or(lhs, rhs) => {
lhs.collect_variables(out);
rhs.collect_variables(out);
}
Self::Not(inner) => inner.collect_variables(out),
}
}
}
fn insert_variable(term: &Term, out: &mut BTreeSet<VariableSymbol>) {
term.collect_variables(out);
}