clasp_rules/lib.rs
1//! Rules engine for CLASP
2//!
3//! Evaluates conditional rules triggered by state changes and events,
4//! producing actions that the router executes. Rules are managed as
5//! CLASP state at `/clasp/rules/{rule_id}`.
6//!
7//! # Features
8//!
9//! - **Trigger types**: OnChange (pattern), OnThreshold, OnEvent, OnInterval
10//! - **Conditions**: Compare current state values before firing
11//! - **Actions**: Set params, publish events, transform trigger values
12//! - **Loop prevention**: Actions from rules are marked with `origin: "rule:{id}"`
13//! and skip rule evaluation
14//! - **Cooldown**: Minimum time between rule firings
15//!
16//! # Example
17//!
18//! ```
19//! use clasp_rules::{RulesEngine, Rule, Trigger, RuleAction, Transform};
20//! use clasp_core::{SignalType, Value};
21//!
22//! let mut engine = RulesEngine::new();
23//!
24//! engine.add_rule(Rule {
25//! id: "motion-lights".to_string(),
26//! name: "Turn on lights when motion detected".to_string(),
27//! enabled: true,
28//! trigger: Trigger::OnChange {
29//! pattern: "/sensor/motion/**".to_string(),
30//! },
31//! conditions: vec![],
32//! actions: vec![RuleAction::Set {
33//! address: "/lights/room1/brightness".to_string(),
34//! value: Value::Float(1.0),
35//! }],
36//! cooldown: None,
37//! }).unwrap();
38//!
39//! let actions = engine.evaluate(
40//! "/sensor/motion/room1",
41//! &Value::Bool(true),
42//! SignalType::Param,
43//! None,
44//! |_addr| None, // state lookup
45//! );
46//!
47//! assert_eq!(actions.len(), 1);
48//! ```
49
50pub mod engine;
51pub mod error;
52pub mod rule;
53
54pub use engine::{PendingAction, RulesEngine};
55pub use error::{Result, RulesError};
56pub use rule::{CompareOp, Condition, Rule, RuleAction, Transform, Trigger};