//! AST types for the filter DSL.
//!
//! See the documentation at <https://mercemay.top/src/ripgrab/> for an overview
//! of how these nodes map back to the source grammar.
pub mod display;
/// The comparison operator used in a [`Expr::Compare`] node.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Cmp {
Eq,
Ne,
Lt,
Le,
Gt,
Ge,
Match,
}
/// A literal value on the right-hand side of a comparison.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Value {
Str(String),
Int(i64),
Regex(String),
}
/// A parsed expression tree.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Expr {
Compare {
field: String,
op: Cmp,
value: Value,
},
And(Box<Expr>, Box<Expr>),
Or(Box<Expr>, Box<Expr>),
Not(Box<Expr>),
}
impl Expr {
/// Walk every subtree and return the set of field names referenced.
///
/// Used by the compiler to check whether a filter needs JSON body parsing
/// or can be evaluated directly against the raw line.
pub fn fields(&self) -> Vec<&str> {
let mut out = Vec::new();
fn walk<'a>(expr: &'a Expr, out: &mut Vec<&'a str>) {
match expr {
Expr::Compare { field, .. } => out.push(field.as_str()),
Expr::And(l, r) | Expr::Or(l, r) => {
walk(l, out);
walk(r, out);
}
Expr::Not(inner) => walk(inner, out),
}
}
walk(self, &mut out);
out.sort();
out.dedup();
out
}
}