zerodds_sql_filter/lib.rs
1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2026 ZeroDDS Contributors
3
4//! OMG DDS Content-Filter-Expression-Parser + Evaluator.
5//!
6//! Safety classification: **SAFE** (reiner Parser + Evaluator, keine
7//! Datenflüsse aus externen Netzen ohne Caller-Vermittlung).
8//!
9//! Spec: OMG DDS 1.4 §B.2.1 "Filter expressions". Die Syntax ist eine
10//! SQL-92-Untermenge, erweitert um `%N`-Parameter-Placeholder.
11//!
12//! # Aktueller Scope
13//!
14//! * Literale: String (`'...'`), Integer (`i64`), Float (`f64`),
15//! Boolean (`TRUE`/`FALSE`).
16//! * Identifier: dotted (`a.b.c`) — für nested Field-Access.
17//! * Parameter-Placeholder: `%0`, `%1`, …
18//! * Vergleichs-Ops: `=`, `!=`, `<>`, `<`, `<=`, `>`, `>=`, `LIKE`.
19//! * Boolean-Ops: `AND`, `OR`, `NOT`.
20//! * Klammern.
21//! * `LIKE`-Wildcards: `%` (mehrere Zeichen), `_` (ein Zeichen).
22//!
23//! Nicht im MVP: `BETWEEN ... AND`, `IN (...)`, `IS NULL`. Die folgen
24//! in 3.7c.
25//!
26//! # Architektur
27//!
28//! 1. `lexer`: Tokenizer. Alle Keywords case-insensitive, String-
29//! Literale `'...'` mit `''`-Escape.
30//! 2. `parser`: Recursive-Descent mit Precedence-Klettern —
31//! `OR` < `AND` < `NOT` < vergleich < atom.
32//! 3. `ast`: Datentypen fuer Expressions + `Value`.
33//! 4. `evaluator`: `Expr::evaluate(row, params)` → `bool`; `row`
34//! implementiert `RowAccess` (Field-Lookup per Name).
35//!
36//! # Verwendung
37//!
38//! ```
39//! use zerodds_sql_filter::{parse, Value, RowAccess};
40//! use std::collections::HashMap;
41//!
42//! struct MapRow(HashMap<String, Value>);
43//! impl RowAccess for MapRow {
44//! fn get(&self, path: &str) -> Option<Value> {
45//! self.0.get(path).cloned()
46//! }
47//! }
48//!
49//! let expr = parse("color = %0 AND x > 10").expect("parse");
50//! let row = MapRow(HashMap::from([
51//! ("color".into(), Value::String("RED".into())),
52//! ("x".into(), Value::Int(42)),
53//! ]));
54//! let params = [Value::String("RED".into())];
55//! assert_eq!(expr.evaluate(&row, ¶ms), Ok(true));
56//! ```
57
58#![cfg_attr(not(feature = "std"), no_std)]
59#![forbid(unsafe_code)]
60#![warn(missing_docs)]
61
62extern crate alloc;
63
64mod ast;
65mod evaluator;
66mod lexer;
67mod parser;
68
69pub use ast::{Expr, Value};
70pub use evaluator::{EvalError, RowAccess};
71pub use parser::{ParseError, parse};