inline_rules_demo/
inline_rules_demo.rs

1use 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    // Define rules directly in code as strings
13    let grl_rules = r#"
14        rule "HighValueCustomer" salience 20 {
15            when
16                Customer.TotalSpent > 1000.0
17            then
18                sendWelcomeEmail(Customer.Email, "GOLD");
19                log("Customer upgraded to GOLD tier");
20        }
21
22        rule "LoyaltyBonus" salience 15 {
23            when
24                Customer.OrderCount >= 10
25            then
26                applyLoyaltyBonus(Customer.Id, 50.0);
27                log("Loyalty bonus applied");
28        }
29
30        rule "NewCustomerWelcome" salience 10 {
31            when
32                Customer.IsNew == false
33            then
34                sendWelcomeEmail(Customer.Email, "EXISTING");
35                log("Welcome email sent to existing customer");
36        }
37
38        rule "LowRiskTransaction" salience 5 {
39            when
40                Transaction.Amount < 1000.0
41            then
42                log("Low-risk transaction processed");
43        }
44    "#;
45
46    println!("šŸ“‹ Inline GRL Rules:");
47    println!("---");
48    println!("{}", grl_rules.trim());
49    println!("---\n");
50
51    // Create facts
52    let facts = Facts::new();
53
54    // Customer data
55    let mut customer_props = HashMap::new();
56    customer_props.insert("Id".to_string(), Value::String("CUST001".to_string()));
57    customer_props.insert(
58        "Email".to_string(),
59        Value::String("john.doe@example.com".to_string()),
60    );
61    customer_props.insert("TotalSpent".to_string(), Value::Number(1250.0)); // Qualifies for GOLD
62    customer_props.insert("YearsActive".to_string(), Value::Integer(4)); // Long-time customer
63    customer_props.insert("OrderCount".to_string(), Value::Integer(12)); // Qualifies for loyalty
64    customer_props.insert("Tier".to_string(), Value::String("SILVER".to_string()));
65    customer_props.insert("IsNew".to_string(), Value::Boolean(false));
66    customer_props.insert("RiskScore".to_string(), Value::Integer(35)); // Low risk
67    customer_props.insert("WelcomeEmailSent".to_string(), Value::Boolean(false));
68
69    // Transaction data
70    let mut transaction_props = HashMap::new();
71    transaction_props.insert("Id".to_string(), Value::String("TXN001".to_string()));
72    transaction_props.insert("Amount".to_string(), Value::Number(750.0)); // Normal amount
73    transaction_props.insert("Currency".to_string(), Value::String("USD".to_string()));
74
75    facts.add_value("Customer", Value::Object(customer_props))?;
76    facts.add_value("Transaction", Value::Object(transaction_props))?;
77
78    println!("šŸ Initial state:");
79    if let Some(customer) = facts.get("Customer") {
80        println!("   Customer = {customer:?}");
81    }
82    if let Some(transaction) = facts.get("Transaction") {
83        println!("   Transaction = {transaction:?}");
84    }
85    println!();
86
87    // Create knowledge base and parse inline rules
88    let kb = KnowledgeBase::new("InlineRulesDemo");
89
90    println!("šŸ”§ Parsing inline GRL rules...");
91    let parsed_rules = GRLParser::parse_rules(grl_rules)
92        .map_err(|e| format!("Failed to parse inline GRL rules: {:?}", e))?;
93
94    println!(
95        "āœ… Successfully parsed {} rules from inline strings",
96        parsed_rules.len()
97    );
98    for rule in parsed_rules {
99        println!("   šŸ“‹ Rule: {} (salience: {})", rule.name, rule.salience);
100        let _ = kb.add_rule(rule);
101    }
102    println!();
103
104    // Create engine with configuration
105    let config = EngineConfig {
106        debug_mode: true,
107        max_cycles: 2,
108        ..Default::default()
109    };
110    let mut engine = RustRuleEngine::with_config(kb, config);
111
112    // Register custom functions called from the inline rules
113    println!("šŸ“ Registering custom functions for inline rules...");
114
115    // Customer tier management
116    engine.register_function("Customer.setTier", |args, _facts| {
117        let new_tier = args.get(0).unwrap().to_string();
118
119        let result = format!("šŸ† Customer tier updated to: {}", new_tier);
120        println!("  {}", result);
121        Ok(Value::String(result))
122    });
123
124    // Email service
125    engine.register_function("sendWelcomeEmail", |args, _facts| {
126        let email = args.get(0).unwrap().to_string();
127        let tier = args.get(1).unwrap().to_string();
128
129        let result = format!("šŸ“§ Welcome email sent to {} for {} tier", email, tier);
130        println!("  {}", result);
131        Ok(Value::String(result))
132    });
133
134    // Loyalty system
135    engine.register_function("applyLoyaltyBonus", |args, _facts| {
136        let customer_id = args.get(0).unwrap().to_string();
137        let bonus_amount = args.get(1).unwrap();
138
139        let result = format!(
140            "šŸ’° Loyalty bonus of {:?} applied to customer {}",
141            bonus_amount, customer_id
142        );
143        println!("  {}", result);
144        Ok(Value::String(result))
145    });
146
147    // Security functions
148    engine.register_function("flagForReview", |args, _facts| {
149        let transaction_id = args.get(0).unwrap().to_string();
150
151        let result = format!(
152            "🚨 Transaction {} flagged for manual review",
153            transaction_id
154        );
155        println!("  {}", result);
156        Ok(Value::String(result))
157    });
158
159    engine.register_function("notifySecurityTeam", |args, _facts| {
160        let customer_id = args.get(0).unwrap().to_string();
161        let amount = args.get(1).unwrap();
162
163        let result = format!(
164            "šŸ”’ Security team notified: Customer {} - Amount {:?}",
165            customer_id, amount
166        );
167        println!("  {}", result);
168        Ok(Value::String(result))
169    });
170
171    // Customer status updates
172    engine.register_function("Customer.setWelcomeEmailSent", |args, _facts| {
173        let sent = args.get(0).unwrap();
174
175        let result = format!("āœ… Welcome email status updated: {:?}", sent);
176        println!("  {}", result);
177        Ok(Value::String(result))
178    });
179
180    println!("āœ… Registered 6 custom functions for inline rules:");
181    println!("   šŸ† Customer.setTier");
182    println!("   šŸ“§ sendWelcomeEmail");
183    println!("   šŸ’° applyLoyaltyBonus");
184    println!("   🚨 flagForReview");
185    println!("   šŸ”’ notifySecurityTeam");
186    println!("   āœ… Customer.setWelcomeEmailSent");
187    println!();
188
189    // Execute the inline rules
190    println!("šŸš€ Executing inline GRL rules...");
191    let result = engine.execute(&facts)?;
192
193    println!("\nšŸ“Š Inline Rules Execution Results:");
194    println!("   Cycles: {}", result.cycle_count);
195    println!("   Rules evaluated: {}", result.rules_evaluated);
196    println!("   Rules fired: {}", result.rules_fired);
197    println!("   Execution time: {:?}", result.execution_time);
198
199    println!("\nšŸ Final state:");
200    if let Some(customer) = facts.get("Customer") {
201        println!("   Customer = {customer:?}");
202    }
203    if let Some(transaction) = facts.get("Transaction") {
204        println!("   Transaction = {transaction:?}");
205    }
206
207    println!("\nšŸŽÆ Inline GRL Rules Demonstrated:");
208    println!("   šŸ“ Rules defined as strings directly in code");
209    println!("   šŸ”§ No external files needed");
210    println!("   ⚔ Quick prototyping and testing");
211    println!("   šŸ† Customer tier management");
212    println!("   šŸ’° Loyalty bonus system");
213    println!("   šŸ”’ Security and fraud detection");
214    println!("   šŸ“§ Email notification system");
215
216    Ok(())
217}