rust_rule_engine/lib.rs
1//! # Rust Rule Engine v1.19.0 - Array Operators & String Methods Edition
2//!
3//! A high-performance rule engine for Rust with **RETE-UL algorithm**, **Array Membership (`in`) operator**,
4//! **String Methods (startsWith, endsWith)**, **Plugin System**, and **GRL (Grule Rule Language)** support.
5//! Features forward/backward chaining, stream processing, and production-ready performance.
6//!
7//! ## What's New in v1.19.0
8//!
9//! - **🎯 `in` Operator**: Array membership checks - `User.role in ["admin", "moderator"]`
10//! - **🔤 String Methods**: Fixed `startsWith` and `endsWith` support in GRL parser
11//! - **📦 Array Literals**: Full support for `["value1", "value2", 123, true]` syntax
12//! - **✅ 154 Tests**: All tests passing including new operator tests
13//!
14//! ## Features
15//!
16//! - **🔌 Plugin System**: Modular plugin architecture with lifecycle management
17//! - **🛠️ Built-in Plugin Suite**: 44+ actions & 33+ functions for common operations
18//! - **🔥 GRL Support**: Full Grule-compatible syntax
19//! - **🎯 Method Calls**: `$Object.method(args)` and property access
20//! - **📊 Knowledge Base**: Centralized rule management with salience
21//! - **💾 Working Memory**: Facts system for complex object interactions
22//! - **⚡ High Performance**: Optimized execution with cycle detection
23//! - **🔄 Arithmetic**: Complex calculations in conditions and actions
24//! - **🛡️ Type Safety**: Rust's type system ensures runtime safety
25//!
26//! ## Quick Start with Plugins
27//!
28//! ```rust
29//! use rust_rule_engine::*;
30//!
31//! fn main() -> Result<()> {
32//! // Create Knowledge Base and Engine
33//! let kb = KnowledgeBase::new("Demo");
34//! let mut engine = RustRuleEngine::new(kb);
35//! let mut facts = Facts::new();
36//!
37//! // Set up data
38//! facts.set("user.age", Value::Number(25.0));
39//! facts.set("user.premium", Value::Boolean(false));
40//!
41//! // Define GRL rule
42//! let rule = r#"
43//! rule "PremiumUpgrade" salience 10 {
44//! when
45//! user.age >= 18 && user.premium == false
46//! then
47//! user.premium = true;
48//! user.discount = 0.1;
49//! }
50//! "#;
51//!
52//! // Parse and add rule to knowledge base
53//! let rules = GRLParser::parse_rules(rule)?;
54//! for r in rules {
55//! engine.knowledge_base().add_rule(r)?;
56//! }
57//!
58//! // Execute with facts
59//! let result = engine.execute(&facts)?;
60//! println!("User premium status: {:?}", facts.get("user.premium"));
61//!
62//! Ok(())
63//! }
64//! ```
65//!
66//! Built-in Plugin Suite provides comprehensive functionality for common operations:
67//!
68//! - **String Utilities**: 8 actions, 5 functions for text manipulation
69//! - **Math Operations**: 10 actions, 6 functions for calculations
70//! - **Date/Time**: 8 actions, 7 functions for temporal operations
71//! - Actions: CurrentDate, CurrentTime, FormatDate, ParseDate, AddDays, AddHours, DateDiff, IsWeekend
72//! - Functions: now, today, dayOfWeek, dayOfYear, year, month, day
73//!
74//! ### Validation (8 actions, 6 functions)
75//! - Actions: ValidateEmail, ValidatePhone, ValidateUrl, ValidateRegex, ValidateRange, ValidateLength, ValidateNotEmpty, ValidateNumeric
76//! - Functions: isEmail, isPhone, isUrl, isNumeric, isEmpty, inRange
77//!
78//! ### Collections (10 actions, 9 functions)
79//! - Actions: ArrayLength, ArrayPush, ArrayPop, ArraySort, ArrayFilter, ArrayMap, ArrayFind, ObjectKeys, ObjectValues, ObjectMerge
80//! - Functions: length, contains, first, last, reverse, join, slice, keys, values
81//!
82//! // Create engine
83//! let mut engine = RustRuleEngine::new(kb);
84//!
85//! // Create facts
86//! let facts = Facts::new();
87//! let user = FactHelper::create_user("john", 25, "john@email.com", "US", false);
88//! facts.add_value("User", user)?;
89//!
90//! // Execute rules
91//! let result = engine.execute(&facts)?;
92//! println!("Rules fired: {}", result.rules_fired);
93//!
94//! Ok(())
95//! }
96//! ```
97
98// TODO: Re-enable missing_docs after documenting all public items
99// #![warn(missing_docs)]
100#![warn(clippy::all)]
101
102/// Backward chaining (goal-driven reasoning) - requires 'backward-chaining' feature
103#[cfg(feature = "backward-chaining")]
104pub mod backward;
105/// Rule execution engine and related components
106pub mod engine;
107/// Error types and result handling
108pub mod errors;
109/// Expression evaluation (arithmetic operations)
110pub mod expression;
111/// Rule parsing and language support
112pub mod parser;
113/// Built-in plugin system for extended functionality
114pub mod plugins;
115/// RETE module for rule evaluation
116pub mod rete;
117/// Streaming rule engine for real-time event processing
118#[cfg(feature = "streaming")]
119pub mod streaming;
120/// Core type definitions for values, operators, and actions
121pub mod types;
122
123// Re-export core types for easy access
124pub use errors::{Result, RuleEngineError};
125pub use types::{ActionType, LogicalOperator, Operator, Value};
126
127// Re-export Grule-style components
128pub use engine::engine::{EngineConfig, GruleExecutionResult, RustRuleEngine};
129pub use engine::facts::{FactHelper, Facts};
130pub use engine::knowledge_base::KnowledgeBase;
131pub use engine::rule::{Condition, ConditionGroup, Rule};
132
133// Re-export parsers
134pub use parser::grl::GRLParser;
135
136/// Builder pattern for creating a RustRuleEngine with various configurations
137pub struct RuleEngineBuilder {
138 kb: KnowledgeBase,
139 config: EngineConfig,
140}
141
142impl RuleEngineBuilder {
143 /// Create a new RuleEngineBuilder
144 pub fn new() -> Self {
145 Self {
146 kb: KnowledgeBase::new("DefaultKB"),
147 config: EngineConfig::default(),
148 }
149 }
150
151 /// Add rules from a .grl file
152 pub fn with_rule_file<P: AsRef<std::path::Path>>(self, path: P) -> Result<Self> {
153 let content = std::fs::read_to_string(path)?;
154 let rules = GRLParser::parse_rules(&content)?;
155
156 for rule in rules {
157 self.kb.add_rule(rule)?;
158 }
159
160 Ok(self)
161 }
162
163 /// Add rules from inline GRL string
164 pub fn with_inline_grl(self, grl_content: &str) -> Result<Self> {
165 let rules = GRLParser::parse_rules(grl_content)?;
166
167 for rule in rules {
168 self.kb.add_rule(rule)?;
169 }
170
171 Ok(self)
172 }
173
174 /// Set engine configuration
175 pub fn with_config(mut self, config: EngineConfig) -> Self {
176 self.config = config;
177 self
178 }
179
180 /// Build the RustRuleEngine
181 pub fn build(self) -> RustRuleEngine {
182 RustRuleEngine::with_config(self.kb, self.config)
183 }
184}
185
186impl Default for RuleEngineBuilder {
187 fn default() -> Self {
188 Self::new()
189 }
190}