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() -> std::result::Result<(), Box<dyn std::error::Error>> {
9 println!("=== E-commerce Rules Demo ===");
10 println!("==============================\n");
11
12 let mut customer_props = HashMap::new();
14 customer_props.insert("IsNew".to_string(), Value::Boolean(true));
15 customer_props.insert(
16 "Membership".to_string(),
17 Value::String("standard".to_string()),
18 );
19 customer_props.insert("TotalSpent".to_string(), Value::Number(750.0));
20 customer_props.insert("WelcomeEmailSent".to_string(), Value::Boolean(false));
21
22 let mut order_props = HashMap::new();
24 order_props.insert("Total".to_string(), Value::Number(75.0));
25 order_props.insert("ItemCount".to_string(), Value::Integer(2));
26 order_props.insert(
27 "Category".to_string(),
28 Value::String("clothing".to_string()),
29 );
30 order_props.insert("DiscountRate".to_string(), Value::Number(0.0));
31 order_props.insert("FreeShipping".to_string(), Value::Boolean(false));
32 order_props.insert(
33 "DiscountType".to_string(),
34 Value::String("none".to_string()),
35 );
36
37 let mut promotion_props = HashMap::new();
39 promotion_props.insert("SeasonalDiscount".to_string(), Value::Number(0.05));
40 promotion_props.insert("BulkDiscount".to_string(), Value::Number(0.10));
41 promotion_props.insert("Active".to_string(), Value::Boolean(true));
42
43 let facts = Facts::new();
45 facts.add_value("Customer", Value::Object(customer_props))?;
46 facts.add_value("Order", Value::Object(order_props))?;
47 facts.add_value("Promotion", Value::Object(promotion_props))?;
48
49 println!("š Initial e-commerce data:");
50 if let Some(customer) = facts.get("Customer") {
51 println!(" Customer = {customer:?}");
52 }
53 if let Some(order) = facts.get("Order") {
54 println!(" Order = {order:?}");
55 }
56 if let Some(promotion) = facts.get("Promotion") {
57 println!(" Promotion = {promotion:?}");
58 }
59 println!();
60
61 let mut kb = KnowledgeBase::new("EcommerceRules");
63
64 let new_customer_rule = Rule::new(
66 "NewCustomerDiscount".to_string(),
67 ConditionGroup::and(
68 ConditionGroup::single(Condition::new(
69 "Customer.IsNew".to_string(),
70 Operator::Equal,
71 Value::Boolean(true),
72 )),
73 ConditionGroup::single(Condition::new(
74 "Order.Total".to_string(),
75 Operator::GreaterThan,
76 Value::Number(50.0),
77 )),
78 ),
79 vec![
80 ActionType::MethodCall {
81 object: "Order".to_string(),
82 method: "setDiscountRate".to_string(),
83 args: vec![Value::Number(0.10)],
84 },
85 ActionType::MethodCall {
86 object: "Order".to_string(),
87 method: "setDiscountType".to_string(),
88 args: vec![Value::String("welcome".to_string())],
89 },
90 ActionType::MethodCall {
91 object: "Customer".to_string(),
92 method: "setWelcomeEmailSent".to_string(),
93 args: vec![Value::Boolean(true)],
94 },
95 ActionType::Call {
96 function: "log".to_string(),
97 args: vec![Value::String(
98 "New customer welcome discount applied".to_string(),
99 )],
100 },
101 ],
102 )
103 .with_salience(25);
104
105 let premium_member_rule = Rule::new(
107 "PremiumMemberBenefits".to_string(),
108 ConditionGroup::and(
109 ConditionGroup::single(Condition::new(
110 "Customer.Membership".to_string(),
111 Operator::Equal,
112 Value::String("premium".to_string()),
113 )),
114 ConditionGroup::single(Condition::new(
115 "Order.Total".to_string(),
116 Operator::GreaterThan,
117 Value::Number(100.0),
118 )),
119 ),
120 vec![
121 ActionType::MethodCall {
122 object: "Order".to_string(),
123 method: "setDiscountRate".to_string(),
124 args: vec![Value::Number(0.15)],
125 },
126 ActionType::MethodCall {
127 object: "Order".to_string(),
128 method: "setFreeShipping".to_string(),
129 args: vec![Value::Boolean(true)],
130 },
131 ActionType::Call {
132 function: "log".to_string(),
133 args: vec![Value::String("Premium member benefits applied".to_string())],
134 },
135 ],
136 )
137 .with_salience(20);
138
139 let vip_upgrade_rule = Rule::new(
141 "VIPUpgrade".to_string(),
142 ConditionGroup::and(
143 ConditionGroup::single(Condition::new(
144 "Customer.TotalSpent".to_string(),
145 Operator::GreaterThan,
146 Value::Number(1000.0),
147 )),
148 ConditionGroup::single(Condition::new(
149 "Customer.Membership".to_string(),
150 Operator::NotEqual,
151 Value::String("VIP".to_string()),
152 )),
153 ),
154 vec![
155 ActionType::MethodCall {
156 object: "Customer".to_string(),
157 method: "setMembership".to_string(),
158 args: vec![Value::String("VIP".to_string())],
159 },
160 ActionType::MethodCall {
161 object: "Order".to_string(),
162 method: "setDiscountRate".to_string(),
163 args: vec![Value::Number(0.25)],
164 },
165 ActionType::Call {
166 function: "log".to_string(),
167 args: vec![Value::String(
168 "Customer upgraded to VIP membership".to_string(),
169 )],
170 },
171 ],
172 )
173 .with_salience(30);
174
175 let free_shipping_rule = Rule::new(
177 "FreeShippingLargeOrders".to_string(),
178 ConditionGroup::single(Condition::new(
179 "Order.Total".to_string(),
180 Operator::GreaterThanOrEqual,
181 Value::Number(100.0),
182 )),
183 vec![
184 ActionType::MethodCall {
185 object: "Order".to_string(),
186 method: "setFreeShipping".to_string(),
187 args: vec![Value::Boolean(true)],
188 },
189 ActionType::Call {
190 function: "log".to_string(),
191 args: vec![Value::String(
192 "Free shipping applied for large order".to_string(),
193 )],
194 },
195 ],
196 )
197 .with_salience(15);
198
199 let bulk_discount_rule = Rule::new(
201 "BulkDiscount".to_string(),
202 ConditionGroup::single(Condition::new(
203 "Order.ItemCount".to_string(),
204 Operator::GreaterThanOrEqual,
205 Value::Integer(5),
206 )),
207 vec![
208 ActionType::Call {
209 function: "max".to_string(),
210 args: vec![
211 Value::String("Order.DiscountRate".to_string()),
212 Value::Number(0.10),
213 ],
214 },
215 ActionType::Call {
216 function: "log".to_string(),
217 args: vec![Value::String("Bulk discount applied".to_string())],
218 },
219 ],
220 )
221 .with_salience(12);
222
223 let seasonal_promotion_rule = Rule::new(
225 "SeasonalPromotion".to_string(),
226 ConditionGroup::and(
227 ConditionGroup::single(Condition::new(
228 "Promotion.Active".to_string(),
229 Operator::Equal,
230 Value::Boolean(true),
231 )),
232 ConditionGroup::single(Condition::new(
233 "Order.Category".to_string(),
234 Operator::Equal,
235 Value::String("clothing".to_string()),
236 )),
237 ),
238 vec![
239 ActionType::Call {
240 function: "max".to_string(),
241 args: vec![
242 Value::String("Order.DiscountRate".to_string()),
243 Value::String("Promotion.SeasonalDiscount".to_string()),
244 ],
245 },
246 ActionType::Call {
247 function: "log".to_string(),
248 args: vec![Value::String("Seasonal promotion applied".to_string())],
249 },
250 ],
251 )
252 .with_salience(10);
253
254 let _ = kb.add_rule(new_customer_rule);
256 let _ = kb.add_rule(premium_member_rule);
257 let _ = kb.add_rule(vip_upgrade_rule);
258 let _ = kb.add_rule(free_shipping_rule);
259 let _ = kb.add_rule(bulk_discount_rule);
260 let _ = kb.add_rule(seasonal_promotion_rule);
261
262 println!(
263 "š Knowledge Base loaded with {} rules",
264 kb.get_statistics().total_rules
265 );
266 println!("š„ Rules: {:?}\n", kb.get_rule_names());
267
268 let config = EngineConfig {
270 debug_mode: true,
271 max_cycles: 5,
272 ..Default::default()
273 };
274 let engine = RustRuleEngine::with_config(kb, config);
275
276 println!("š Executing e-commerce rules...");
278 let result = engine.execute(&facts)?;
279
280 println!("\nš E-commerce Execution Results:");
281 println!(" Cycles: {}", result.cycle_count);
282 println!(" Rules evaluated: {}", result.rules_evaluated);
283 println!(" Rules fired: {}", result.rules_fired);
284 println!(" Execution time: {:?}", result.execution_time);
285
286 println!("\nš Final e-commerce state:");
287 if let Some(customer) = facts.get("Customer") {
288 println!(" Customer = {customer:?}");
289 }
290 if let Some(order) = facts.get("Order") {
291 println!(" Order = {order:?}");
292 }
293 if let Some(promotion) = facts.get("Promotion") {
294 println!(" Promotion = {promotion:?}");
295 }
296
297 println!("\nšÆ E-commerce Rules Demonstrated:");
298 println!(" š New Customer Welcome Discount");
299 println!(" š Premium Member Benefits");
300 println!(" š VIP Membership Upgrades");
301 println!(" š Free Shipping Rules");
302 println!(" š¦ Bulk Purchase Discounts");
303 println!(" š·ļø Seasonal Promotions");
304
305 Ok(())
306}