rule_file_functions_demo/
rule_file_functions_demo.rs1use rust_rule_engine::engine::facts::Facts;
2use rust_rule_engine::engine::knowledge_base::KnowledgeBase;
3use rust_rule_engine::engine::{EngineConfig, RustRuleEngine};
4use rust_rule_engine::parser::SimpleGRLParser;
5use rust_rule_engine::types::Value;
6use std::collections::HashMap;
7use std::fs;
8
9fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
10 println!("šÆ Custom Functions from Rule File Demo");
11 println!("=======================================\n");
12
13 let rule_file_path = "examples/rules/car_functions.grl";
15 println!("š Reading rules from file: {}", rule_file_path);
16
17 let rule_content = fs::read_to_string(rule_file_path)
18 .map_err(|e| format!("Failed to read rule file: {}", e))?;
19
20 println!("š Rule file content:");
21 println!("---");
22 println!("{}", rule_content);
23 println!("---\n");
24
25 let facts = Facts::new();
27
28 let mut car_props = HashMap::new();
30 car_props.insert("Speed".to_string(), Value::Number(95.0)); car_props.insert("MaxSpeed".to_string(), Value::Number(120.0));
32 car_props.insert("Engine".to_string(), Value::String("V6".to_string()));
33 car_props.insert("IsRunning".to_string(), Value::Boolean(true));
34
35 let mut driver_props = HashMap::new();
37 driver_props.insert("Name".to_string(), Value::String("John Doe".to_string()));
38 driver_props.insert("Experience".to_string(), Value::Integer(7)); driver_props.insert("License".to_string(), Value::String("VALID".to_string()));
40
41 facts.add_value("Car", Value::Object(car_props))?;
42 facts.add_value("Driver", Value::Object(driver_props))?;
43
44 println!("š Initial state:");
45 if let Some(car) = facts.get("Car") {
46 println!(" Car = {car:?}");
47 }
48 if let Some(driver) = facts.get("Driver") {
49 println!(" Driver = {driver:?}");
50 }
51 println!();
52
53 let mut kb = KnowledgeBase::new("RuleFileDemo");
55
56 println!("š§ Parsing GRL file content...");
58 let parsed_rules = SimpleGRLParser::parse_rules(&rule_content)
59 .map_err(|e| format!("Failed to parse GRL file: {:?}", e))?;
60
61 println!(
62 "ā
Successfully parsed {} rules from file",
63 parsed_rules.len()
64 );
65 for rule in parsed_rules {
66 println!(" š Rule: {} (salience: {})", rule.name, rule.salience);
67 let _ = kb.add_rule(rule);
68 }
69 println!();
70
71 let config = EngineConfig {
73 debug_mode: true,
74 max_cycles: 3,
75 ..Default::default()
76 };
77 let mut engine = RustRuleEngine::with_config(kb, config);
78
79 println!("š Registering custom functions from rule file...");
81
82 engine.register_function("checkSpeedLimit", |args, facts| {
84 let speed_field = args.get(0).unwrap().to_string();
85 let limit = args.get(1).unwrap();
86
87 let speed = if let Some(car) = facts.get("Car") {
88 if let Value::Object(obj) = car {
89 obj.get("Speed").cloned().unwrap_or(Value::Number(0.0))
90 } else {
91 Value::Number(0.0)
92 }
93 } else {
94 Value::Number(0.0)
95 };
96
97 let result = format!("š¦ Speed check: {:?} vs limit {:?}", speed, limit);
98 println!("{}", result);
99 Ok(Value::String(result))
100 });
101
102 engine.register_function("sendAlert", |args, facts| {
103 let message = args.get(0).unwrap().to_string();
104 let driver_field = args.get(1).unwrap().to_string();
105
106 let driver_name = if let Some(driver) = facts.get("Driver") {
107 if let Value::Object(obj) = driver {
108 obj.get("Name")
109 .cloned()
110 .unwrap_or(Value::String("Unknown".to_string()))
111 } else {
112 Value::String("Unknown".to_string())
113 }
114 } else {
115 Value::String("Unknown".to_string())
116 };
117
118 let alert = format!("šØ ALERT to {:?}: {}", driver_name, message);
119 println!("{}", alert);
120 Ok(Value::String(alert))
121 });
122
123 engine.register_function("validateDriver", |args, _facts| {
125 let name_field = args.get(0).unwrap().to_string();
126 let exp_field = args.get(1).unwrap().to_string();
127
128 let result = format!(
129 "ā
Driver validation: {} (experience: {})",
130 name_field, exp_field
131 );
132 println!("{}", result);
133 Ok(Value::String(result))
134 });
135
136 engine.register_function("calculateInsurance", |args, _facts| {
137 let exp_field = args.get(0).unwrap().to_string();
138 let engine_field = args.get(1).unwrap().to_string();
139
140 let result = format!(
141 "š° Insurance: Experience {} + Engine {} = Premium",
142 exp_field, engine_field
143 );
144 println!("{}", result);
145 Ok(Value::String(result))
146 });
147
148 engine.register_function("performDiagnostics", |args, _facts| {
150 let engine_field = args.get(0).unwrap().to_string();
151 let speed_field = args.get(1).unwrap().to_string();
152
153 let result = format!(
154 "š§ Diagnostics: Engine {} at speed {} - OK",
155 engine_field, speed_field
156 );
157 println!("{}", result);
158 Ok(Value::String(result))
159 });
160
161 engine.register_function("optimizePerformance", |args, _facts| {
162 let current_speed = args.get(0).unwrap().to_string();
163 let max_speed = args.get(1).unwrap().to_string();
164
165 let result = format!(
166 "ā” Performance: {} / {} - Optimized",
167 current_speed, max_speed
168 );
169 println!("{}", result);
170 Ok(Value::String(result))
171 });
172
173 engine.register_function("scheduleMaintenanceCheck", |args, _facts| {
175 let engine_field = args.get(0).unwrap().to_string();
176 let exp_field = args.get(1).unwrap().to_string();
177
178 let result = format!(
179 "š§ Maintenance scheduled: Engine {} (driver exp: {})",
180 engine_field, exp_field
181 );
182 println!("{}", result);
183 Ok(Value::String(result))
184 });
185
186 engine.register_function("updateMaintenanceRecord", |args, _facts| {
187 let name_field = args.get(0).unwrap().to_string();
188 let engine_field = args.get(1).unwrap().to_string();
189
190 let result = format!("š Record updated: {} - {}", name_field, engine_field);
191 println!("{}", result);
192 Ok(Value::String(result))
193 });
194
195 println!("ā
Registered {} custom functions from rule file:", 8);
196 println!(" š¦ checkSpeedLimit");
197 println!(" šØ sendAlert");
198 println!(" ā
validateDriver");
199 println!(" š° calculateInsurance");
200 println!(" š§ performDiagnostics");
201 println!(" ā” optimizePerformance");
202 println!(" š§ scheduleMaintenanceCheck");
203 println!(" š updateMaintenanceRecord");
204 println!();
205
206 println!("š Executing rules from file...");
208 let result = engine.execute(&facts)?;
209
210 println!("\nš Rule File Execution Results:");
211 println!(" Cycles: {}", result.cycle_count);
212 println!(" Rules evaluated: {}", result.rules_evaluated);
213 println!(" Rules fired: {}", result.rules_fired);
214 println!(" Execution time: {:?}", result.execution_time);
215
216 println!("\nš Final state:");
217 if let Some(car) = facts.get("Car") {
218 println!(" Car = {car:?}");
219 }
220 if let Some(driver) = facts.get("Driver") {
221 println!(" Driver = {driver:?}");
222 }
223
224 println!("\nšÆ Rule File Custom Functions Demonstrated:");
225 println!(" š Rules defined in external .grl file");
226 println!(" š Custom functions called from rule file");
227 println!(" š§ Business logic separated from rule definitions");
228 println!(" š File-based rule management");
229 println!(" ā” Function registry with rule file integration");
230
231 Ok(())
232}