src/filter/dsl/mod.rs

//! Small filter language used by the `--where` flag.
//!
//! The DSL supports comparisons (`=`, `!=`, `<`, `<=`, `>`, `>=`), regex match
//! (`~`), and boolean combinators `and`, `or`, `not`. See the crate-level
//! documentation at <https://mercemay.top/src/ripgrab/> for grammar details.

pub mod ast;
pub mod compile;
pub mod error;
pub mod eval;
pub mod parser;

pub use ast::Expr;
pub use compile::{CompiledFilter, compile};
pub use error::{DslError, DslResult};
pub use eval::{EvalContext, evaluate};
pub use parser::parse;

/// Parse and compile a filter expression in one step.
///
/// This is the common entry point used by the CLI. Callers that need access to
/// the AST (for syntax highlighting, for instance) should call [`parse`] then
/// [`compile`] themselves.
pub fn parse_and_compile(input: &str) -> DslResult<CompiledFilter> {
    let ast = parse(input)?;
    compile(&ast)
}

#[cfg(test)]
mod smoke {
    use super::*;

    #[test]
    fn compiles_trivial_expression() {
        let compiled = parse_and_compile("status >= 400").unwrap();
        let mut ctx = EvalContext::new();
        ctx.set("status", "503");
        assert!(evaluate(&compiled, &ctx));
    }

    #[test]
    fn rejects_syntax_garbage() {
        assert!(parse_and_compile("status >= ").is_err());
    }
}