generic_method_calls/
generic_method_calls.rs

1use rust_rule_engine::engine::facts::Facts;
2use rust_rule_engine::engine::knowledge_base::KnowledgeBase;
3use rust_rule_engine::engine::rule::{Condition, ConditionGroup, Rule};
4use rust_rule_engine::engine::{EngineConfig, RustRuleEngine};
5use rust_rule_engine::types::{ActionType, Operator, Value};
6use std::collections::HashMap;
7
8fn main() -> Result<(), Box<dyn std::error::Error>> {
9    println!("=== Demo: Generic Method Calls ===\n");
10
11    // Create objects with various properties
12    let mut car_props = HashMap::new();
13    car_props.insert("Speed".to_string(), Value::Number(50.0));
14    car_props.insert("Fuel".to_string(), Value::Number(80.0));
15    car_props.insert("Brand".to_string(), Value::String("Toyota".to_string()));
16
17    let mut account_props = HashMap::new();
18    account_props.insert("Balance".to_string(), Value::Number(1000.0));
19    account_props.insert("Owner".to_string(), Value::String("John Doe".to_string()));
20    account_props.insert("Active".to_string(), Value::Boolean(true));
21
22    // Create facts
23    let facts = Facts::new();
24    facts.add_value("Car", Value::Object(car_props))?;
25    facts.add_value("Account", Value::Object(account_props))?;
26
27    println!("šŸ Initial state:");
28    if let Some(car) = facts.get("Car") {
29        println!("   Car = {car:?}");
30    }
31    if let Some(account) = facts.get("Account") {
32        println!("   Account = {account:?}");
33    }
34    println!();
35
36    // Create knowledge base
37    let mut kb = KnowledgeBase::new("GenericMethodDemo");
38
39    // Rule 1: Speed up car if speed < 60
40    let speed_rule = Rule::new(
41        "SpeedUpCar".to_string(),
42        ConditionGroup::single(Condition::new(
43            "Car.Speed".to_string(),
44            Operator::LessThan,
45            Value::Number(60.0),
46        )),
47        vec![ActionType::MethodCall {
48            object: "Car".to_string(),
49            method: "setSpeed".to_string(), // Generic setter
50            args: vec![Value::Number(75.0)],
51        }],
52    )
53    .with_salience(10);
54
55    // Rule 2: Withdraw from account if balance > 500
56    let withdraw_rule = Rule::new(
57        "WithdrawMoney".to_string(),
58        ConditionGroup::single(Condition::new(
59            "Account.Balance".to_string(),
60            Operator::GreaterThan,
61            Value::Number(500.0),
62        )),
63        vec![ActionType::MethodCall {
64            object: "Account".to_string(),
65            method: "setBalance".to_string(), // Generic setter
66            args: vec![Value::Number(800.0)],
67        }],
68    )
69    .with_salience(5);
70
71    // Rule 3: Update car brand using generic setter
72    let brand_rule = Rule::new(
73        "UpdateBrand".to_string(),
74        ConditionGroup::single(Condition::new(
75            "Car.Brand".to_string(),
76            Operator::Equal,
77            Value::String("Toyota".to_string()),
78        )),
79        vec![ActionType::MethodCall {
80            object: "Car".to_string(),
81            method: "setBrand".to_string(), // Generic setter
82            args: vec![Value::String("Honda".to_string())],
83        }],
84    )
85    .with_salience(3);
86
87    // Add rules to knowledge base
88    let _ = kb.add_rule(speed_rule);
89    let _ = kb.add_rule(withdraw_rule);
90    let _ = kb.add_rule(brand_rule);
91
92    // Create engine with debug mode
93    let config = EngineConfig {
94        debug_mode: true,
95        max_cycles: 10,
96        ..Default::default()
97    };
98    let engine = RustRuleEngine::with_config(kb, config);
99
100    // Execute rules
101    println!("šŸš€ Executing rules with generic method calls...");
102    let result = engine.execute(&facts)?;
103
104    println!("\nšŸ“Š Execution Results:");
105    println!("   Cycles: {}", result.cycle_count);
106    println!("   Rules evaluated: {}", result.rules_evaluated);
107    println!("   Rules fired: {}", result.rules_fired);
108    println!("   Execution time: {:?}", result.execution_time);
109
110    println!("\nšŸ Final state:");
111    if let Some(car) = facts.get("Car") {
112        println!("   Car = {car:?}");
113    }
114    if let Some(account) = facts.get("Account") {
115        println!("   Account = {account:?}");
116    }
117
118    // Demonstrate generic getters
119    println!("\nšŸ” Testing generic getters:");
120    if let Some(car_value) = facts.get("Car") {
121        if let Value::Object(car_obj) = car_value {
122            println!(
123                "   Car.Speed via getter would return: {:?}",
124                car_obj.get("Speed")
125            );
126            println!(
127                "   Car.Brand via getter would return: {:?}",
128                car_obj.get("Brand")
129            );
130            println!(
131                "   Car.Fuel via getter would return: {:?}",
132                car_obj.get("Fuel")
133            );
134        }
135    }
136
137    Ok(())
138}