1use std::collections::HashMap;
4use std::sync::Arc;
5
6use tokio::sync::RwLock;
7
8use crate::{Rule, RuleResult, RulesError, Result};
9use crate::context::ExecutionContext;
10use crate::conditions::ConditionEvaluator;
11use crate::actions::ActionExecutor;
12
13pub struct RuleEngine {
15 rules: Arc<RwLock<HashMap<String, Rule>>>,
17
18 condition_evaluator: ConditionEvaluator,
20
21 action_executor: ActionExecutor,
23}
24
25impl RuleEngine {
26 pub fn new() -> Self {
28 Self {
29 rules: Arc::new(RwLock::new(HashMap::new())),
30 condition_evaluator: ConditionEvaluator::new(),
31 action_executor: ActionExecutor::new(),
32 }
33 }
34
35 pub async fn add_rule(&mut self, rule: Rule) -> Result<()> {
37 rule.is_valid()?;
38 self.rules.write().await.insert(rule.id.clone(), rule);
39 Ok(())
40 }
41
42 pub async fn execute_rule(&self, rule: &Rule, context: &mut ExecutionContext) -> Result<RuleResult> {
44 if !rule.enabled {
45 return Ok(RuleResult::Skipped);
46 }
47
48 for condition in &rule.conditions {
50 if !self.condition_evaluator.evaluate_condition(condition, context).await? {
51 return Ok(RuleResult::Skipped);
52 }
53 }
54
55 for action in &rule.actions {
57 self.action_executor.execute_action(action, context).await?;
58 }
59
60 Ok(RuleResult::Allow)
61 }
62
63 pub async fn evaluate_condition(&self, condition: &crate::RuleCondition, context: &ExecutionContext) -> Result<bool> {
65 self.condition_evaluator.evaluate_condition(condition, context).await
66 }
67
68 pub async fn execute_action(&self, action: &crate::RuleAction, context: &mut ExecutionContext) -> Result<()> {
70 self.action_executor.execute_action(action, context).await
71 }
72}
73
74impl Default for RuleEngine {
75 fn default() -> Self {
76 Self::new()
77 }
78}