custom_operators/
custom_operators.rs1use fsm_guards::{evaluate, EvalCtx};
6use serde_json::{json, Value};
7use std::sync::Arc;
8
9fn main() {
10 let ctx = EvalCtx::new().with_op("state_in", |args| {
12 Ok(Value::Bool(args[1..].contains(&args[0])))
13 });
14
15 let rule = json!({"state_in": [{"var": "status"}, "active", "pending"]});
16 println!("active → {}", evaluate(&rule, &json!({"status": "active"}), &ctx).unwrap()); println!("blocked → {}", evaluate(&rule, &json!({"status": "blocked"}), &ctx).unwrap()); let ctx = EvalCtx::new()
21 .with_op("state_in", |args| Ok(Value::Bool(args[1..].contains(&args[0]))))
22 .with_op("days_since", |args| {
23 let recorded = args[0].as_f64().unwrap_or(0.0);
25 let now = args[1].as_f64().unwrap_or(0.0);
26 Ok(json!(now - recorded))
27 });
28
29 let rule = json!({"and": [
30 {"state_in": [{"var": "status"}, "active", "pending"]},
31 {"<": [{"days_since": [{"var": "created_at"}, 1722470400.0]}, 30]}
32 ]});
33 let data = json!({"status": "active", "created_at": 1720000000.0});
34 println!("compound: {}", evaluate(&rule, &data, &ctx).unwrap());
35
36 let shared_ctx = Arc::new(
38 EvalCtx::new().with_op("always_true", |_| Ok(Value::Bool(true))),
39 );
40
41 let handles: Vec<_> = (0..4)
42 .map(|i| {
43 let ctx = Arc::clone(&shared_ctx);
44 let rule = json!({"always_true": []});
45 std::thread::spawn(move || {
46 let result = evaluate(&rule, &json!({}), &ctx).unwrap();
47 println!("thread {i}: {result}");
48 })
49 })
50 .collect();
51
52 for h in handles {
53 h.join().unwrap();
54 }
55}