1use super::context::EvaluationContext;
6use super::expression::evaluate_expression;
7use crate::{LemmaError, LemmaRule, OperationResult};
8
9pub fn evaluate_rule(
14 rule: &LemmaRule,
15 context: &mut EvaluationContext,
16) -> Result<OperationResult, LemmaError> {
17 use crate::OperationRecord;
18
19 for (index, unless_clause) in rule.unless_clauses.iter().enumerate().rev() {
21 let condition_result = evaluate_expression(&unless_clause.condition, context)?;
22
23 if let OperationResult::Veto(msg) = condition_result {
25 return Ok(OperationResult::Veto(msg));
26 }
27
28 let condition_value = condition_result.value().unwrap();
29 let matched = match condition_value {
30 crate::LiteralValue::Boolean(b) => *b,
31 _ => {
32 return Err(LemmaError::Engine(
33 "Unless condition must evaluate to boolean".to_string(),
34 ));
35 }
36 };
37
38 if matched {
39 let result = evaluate_expression(&unless_clause.result, context)?;
40
41 if let OperationResult::Veto(msg) = result {
43 return Ok(OperationResult::Veto(msg));
44 }
45
46 let result_value = result.value().unwrap().clone();
47 context
48 .operations
49 .push(OperationRecord::UnlessClauseEvaluated {
50 index,
51 matched: true,
52 result_if_matched: Some(result_value.clone()),
53 });
54 context.operations.push(OperationRecord::FinalResult {
55 value: result_value.clone(),
56 });
57 return Ok(OperationResult::Value(result_value));
58 } else {
59 context
60 .operations
61 .push(OperationRecord::UnlessClauseEvaluated {
62 index,
63 matched: false,
64 result_if_matched: None,
65 });
66 }
67 }
68
69 let default_result = evaluate_expression(&rule.expression, context)?;
71
72 if let OperationResult::Veto(msg) = default_result {
74 return Ok(OperationResult::Veto(msg));
75 }
76
77 let default_value = default_result.value().unwrap().clone();
78 context.operations.push(OperationRecord::DefaultValue {
79 value: default_value.clone(),
80 });
81 context.operations.push(OperationRecord::FinalResult {
82 value: default_value.clone(),
83 });
84 Ok(OperationResult::Value(default_value))
85}