inline_rules_demo/
inline_rules_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::grl_parser::GRLParser;
5use rust_rule_engine::types::Value;
6use std::collections::HashMap;
7
8fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
9 println!("šÆ Inline GRL Rules Demo");
10 println!("========================\n");
11
12 let grl_rules = r#"
14 rule "HighValueCustomer" salience 20 {
15 when
16 Customer.TotalSpent > 1000.0
17 then
18 sendWelcomeEmail(Customer.Email, "GOLD");
19 Customer.setTier("GOLD");
20 log("Customer upgraded to GOLD tier");
21 }
22
23 rule "LoyaltyBonus" salience 15 {
24 when
25 Customer.OrderCount >= 10
26 then
27 applyLoyaltyBonus(Customer.Id, 50.0);
28 Customer.setLoyaltyBonusApplied(true);
29 log("Loyalty bonus applied");
30 }
31
32 rule "NewCustomerWelcome" salience 10 {
33 when
34 Customer.IsNew == false && Customer.WelcomeEmailSent == false
35 then
36 sendWelcomeEmail(Customer.Email, "EXISTING");
37 Customer.setWelcomeEmailSent(true);
38 log("Welcome email sent to existing customer");
39 }
40
41 rule "LowRiskTransaction" salience 5 {
42 when
43 Transaction.Amount < 1000.0 && Transaction.RiskProcessed == false
44 then
45 Transaction.setRiskProcessed(true);
46 log("Low-risk transaction processed");
47 }
48 "#;
49
50 println!("š Inline GRL Rules:");
51 println!("---");
52 println!("{}", grl_rules.trim());
53 println!("---\n");
54
55 let facts = Facts::new();
57
58 let mut customer_props = HashMap::new();
60 customer_props.insert("Id".to_string(), Value::String("CUST001".to_string()));
61 customer_props.insert(
62 "Email".to_string(),
63 Value::String("john.doe@example.com".to_string()),
64 );
65 customer_props.insert("TotalSpent".to_string(), Value::Number(1250.0)); customer_props.insert("YearsActive".to_string(), Value::Integer(4)); customer_props.insert("OrderCount".to_string(), Value::Integer(12)); customer_props.insert("Tier".to_string(), Value::String("SILVER".to_string()));
69 customer_props.insert("IsNew".to_string(), Value::Boolean(false));
70 customer_props.insert("RiskScore".to_string(), Value::Integer(35)); customer_props.insert("WelcomeEmailSent".to_string(), Value::Boolean(false));
72 customer_props.insert("LoyaltyBonusApplied".to_string(), Value::Boolean(false));
73
74 let mut transaction_props = HashMap::new();
76 transaction_props.insert("Id".to_string(), Value::String("TXN001".to_string()));
77 transaction_props.insert("Amount".to_string(), Value::Number(750.0)); transaction_props.insert("Currency".to_string(), Value::String("USD".to_string()));
79 transaction_props.insert("RiskProcessed".to_string(), Value::Boolean(false));
80
81 facts.add_value("Customer", Value::Object(customer_props))?;
82 facts.add_value("Transaction", Value::Object(transaction_props))?;
83
84 println!("š Initial state:");
85 if let Some(customer) = facts.get("Customer") {
86 println!(" Customer = {customer:?}");
87 }
88 if let Some(transaction) = facts.get("Transaction") {
89 println!(" Transaction = {transaction:?}");
90 }
91 println!();
92
93 let kb = KnowledgeBase::new("InlineRulesDemo");
95
96 println!("š§ Parsing inline GRL rules...");
97 let parsed_rules = GRLParser::parse_rules(grl_rules)
98 .map_err(|e| format!("Failed to parse inline GRL rules: {:?}", e))?;
99
100 println!(
101 "ā
Successfully parsed {} rules from inline strings",
102 parsed_rules.len()
103 );
104 for rule in parsed_rules {
105 println!(" š Rule: {} (salience: {})", rule.name, rule.salience);
106 let _ = kb.add_rule(rule);
107 }
108 println!();
109
110 let config = EngineConfig {
112 debug_mode: true,
113 max_cycles: 1, ..Default::default()
115 };
116 let mut engine = RustRuleEngine::with_config(kb, config);
117
118 println!("š Registering custom functions for inline rules...");
120
121 engine.register_function("Customer.setTier", |args, facts| {
123 let new_tier = args.get(0).unwrap().to_string();
124
125 facts
127 .set_nested("Customer.Tier", Value::String(new_tier.clone()))
128 .unwrap();
129
130 let result = format!("š Customer tier updated to: {}", new_tier);
131 println!(" {}", result);
132 Ok(Value::String(result))
133 });
134
135 engine.register_function("Customer.setLoyaltyBonusApplied", |args, facts| {
137 let applied = args.get(0).unwrap();
138
139 facts
141 .set_nested("Customer.LoyaltyBonusApplied", applied.clone())
142 .unwrap();
143
144 let result = format!("šÆ Loyalty bonus status updated: {:?}", applied);
145 println!(" {}", result);
146 Ok(Value::String(result))
147 });
148
149 engine.register_function("sendWelcomeEmail", |args, _facts| {
151 let email = args.get(0).unwrap().to_string();
152 let tier = args.get(1).unwrap().to_string();
153
154 let result = format!("š§ Welcome email sent to {} for {} tier", email, tier);
155 println!(" {}", result);
156 Ok(Value::String(result))
157 });
158
159 engine.register_function("applyLoyaltyBonus", |args, _facts| {
161 let customer_id = args.get(0).unwrap().to_string();
162 let bonus_amount = args.get(1).unwrap();
163
164 let result = format!(
165 "š° Loyalty bonus of {:?} applied to customer {}",
166 bonus_amount, customer_id
167 );
168 println!(" {}", result);
169 Ok(Value::String(result))
170 });
171
172 engine.register_function("flagForReview", |args, _facts| {
174 let transaction_id = args.get(0).unwrap().to_string();
175
176 let result = format!(
177 "šØ Transaction {} flagged for manual review",
178 transaction_id
179 );
180 println!(" {}", result);
181 Ok(Value::String(result))
182 });
183
184 engine.register_function("notifySecurityTeam", |args, _facts| {
185 let customer_id = args.get(0).unwrap().to_string();
186 let amount = args.get(1).unwrap();
187
188 let result = format!(
189 "š Security team notified: Customer {} - Amount {:?}",
190 customer_id, amount
191 );
192 println!(" {}", result);
193 Ok(Value::String(result))
194 });
195
196 engine.register_function("Customer.setWelcomeEmailSent", |args, facts| {
198 let sent = args.get(0).unwrap();
199
200 facts
202 .set_nested("Customer.WelcomeEmailSent", sent.clone())
203 .unwrap();
204
205 let result = format!("ā
Welcome email status updated: {:?}", sent);
206 println!(" {}", result);
207 Ok(Value::String(result))
208 });
209
210 engine.register_function("Transaction.setRiskProcessed", |args, facts| {
212 let processed = args.get(0).unwrap();
213
214 facts
216 .set_nested("Transaction.RiskProcessed", processed.clone())
217 .unwrap();
218
219 let result = format!("ā
Transaction risk processing completed: {:?}", processed);
220 println!(" {}", result);
221 Ok(Value::String(result))
222 });
223
224 println!("ā
Registered 8 custom functions for inline rules:");
225 println!(" š Customer.setTier");
226 println!(" šÆ Customer.setLoyaltyBonusApplied");
227 println!(" š§ sendWelcomeEmail");
228 println!(" š° applyLoyaltyBonus");
229 println!(" šØ flagForReview");
230 println!(" š notifySecurityTeam");
231 println!(" ā
Customer.setWelcomeEmailSent");
232 println!(" ā
Transaction.setRiskProcessed");
233 println!();
234
235 println!("š Executing inline GRL rules...");
237 let result = engine.execute(&facts)?;
238
239 println!("\nš Inline Rules Execution Results:");
240 println!(" Cycles: {}", result.cycle_count);
241 println!(" Rules evaluated: {}", result.rules_evaluated);
242 println!(" Rules fired: {}", result.rules_fired);
243 println!(" Execution time: {:?}", result.execution_time);
244
245 println!("\nš Final state:");
246 if let Some(customer) = facts.get("Customer") {
247 println!(" Customer = {customer:?}");
248 }
249 if let Some(transaction) = facts.get("Transaction") {
250 println!(" Transaction = {transaction:?}");
251 }
252
253 println!("\nšÆ Inline GRL Rules Demonstrated:");
254 println!(" š Rules defined as strings directly in code");
255 println!(" š§ No external files needed");
256 println!(" ā” Quick prototyping and testing");
257 println!(" š Customer tier management");
258 println!(" š° Loyalty bonus system");
259 println!(" š Security and fraud detection");
260 println!(" š§ Email notification system");
261
262 Ok(())
263}