Skip to main content

hyperi_rustlib/expression/
mod.rs

1// Project:   hyperi-rustlib
2// File:      src/expression/mod.rs
3// Purpose:   CEL expression evaluation for DFE components
4// Language:  Rust
5//
6// License:   FSL-1.1-ALv2
7// Copyright: (c) 2026 HYPERI PTY LIMITED
8
9//! CEL expression evaluation -- compile, evaluate, validate.
10//!
11//! Provides a DFE-profile-restricted CEL expression evaluator built on the
12//! [`cel`] crate (renamed from `cel-interpreter`). Both Python (via
13//! `common-expression-language` PyO3 bindings) and Rust use the **same**
14//! underlying Rust crate, ensuring identical parsing and evaluation
15//! semantics across all DFE components.
16//!
17//! # DFE Expression Profile
18//!
19//! Only a high-performance subset of CEL is allowed:
20//!
21//! | Category | Examples |
22//! |----------|---------|
23//! | Comparison | `==`, `!=`, `<`, `<=`, `>`, `>=` |
24//! | Logical | `&&`, `\|\|`, `!` |
25//! | Membership | `in` |
26//! | String | `contains()`, `startsWith()`, `endsWith()` |
27//! | Existence | `has()` |
28//! | Size | `size()` |
29//! | Ternary | `? :` |
30//! | Type casts | `int()`, `double()`, `string()`, `bool()` |
31//! | Arithmetic | `+`, `-`, `*`, `/`, `%` |
32//!
33//! **Restricted (blocked by default, opt-in via [`ProfileConfig`]):**
34//! - Regex: `matches()` -- unbounded cost per record
35//! - Iteration: `map()`, `filter()`, `exists()`, `all()` -- O(n) per collection
36//! - Time: `timestamp()`, `duration()` -- ClickHouse handles natively
37//!
38//! # Usage
39//!
40//! ```rust
41//! use hyperi_rustlib::expression::{compile, evaluate, evaluate_condition, validate};
42//! use std::collections::HashMap;
43//! use serde_json::json;
44//!
45//! // Validate (returns errors list, empty if valid)
46//! assert!(validate(r#"severity == "critical""#).is_empty());
47//!
48//! // One-shot evaluation
49//! let mut data = HashMap::new();
50//! data.insert("amount".into(), json!(15000));
51//! let result = evaluate("amount > 10000", &data).unwrap();
52//! assert_eq!(result, true.into());
53//!
54//! // Boolean condition (missing fields → false)
55//! assert!(!evaluate_condition(r#"severity == "critical""#, &HashMap::new()));
56//!
57//! // Compile for hot-path reuse
58//! let program = compile("score > threshold").unwrap();
59//! // ... program.execute(&context) per record
60//! ```
61//!
62//! See `dfe-engine/docs/EXPRESSIONS-CEL.md` for the full profile specification.
63
64pub mod error;
65pub mod evaluator;
66pub mod profile;
67
68pub use error::{ExpressionError, ExpressionResult};
69pub use evaluator::{
70    build_context, compile, compile_with_config, evaluate, evaluate_condition, validate,
71    validate_with_config,
72};
73pub use profile::{
74    ALLOWED_FUNCTIONS, DISALLOWED_FUNCTIONS, ProfileConfig, RESTRICTED_ITERATION, RESTRICTED_REGEX,
75    RESTRICTED_TIME, check_profile_with_config,
76};