ricecoder_hooks/executor/
condition.rs1use crate::error::{HooksError, Result};
4use crate::types::{Condition, EventContext};
5use tracing::{debug, warn};
6
7pub struct ConditionEvaluator;
13
14impl ConditionEvaluator {
15 pub fn evaluate(condition: &Condition, context: &EventContext) -> Result<bool> {
28 debug!(
29 expression = %condition.expression,
30 context_keys = ?condition.context_keys,
31 "Evaluating condition"
32 );
33
34 for key in &condition.context_keys {
36 if context.data.get(key).is_none() && context.metadata.get(key).is_none() {
37 warn!(
38 key = %key,
39 "Required context key not found for condition evaluation"
40 );
41 return Err(HooksError::InvalidConfiguration(format!(
42 "Required context key '{}' not found",
43 key
44 )));
45 }
46 }
47
48 Ok(true)
55 }
56}
57
58#[cfg(test)]
59mod tests {
60 use super::*;
61 use serde_json::json;
62
63 fn create_test_context() -> EventContext {
64 EventContext {
65 data: json!({
66 "file_path": "/path/to/file.rs",
67 "size": 1024,
68 }),
69 metadata: json!({
70 "user": "alice",
71 "project": "my-project",
72 }),
73 }
74 }
75
76 #[test]
77 fn test_evaluate_condition_with_valid_context() {
78 let condition = Condition {
79 expression: "file_path.ends_with('.rs')".to_string(),
80 context_keys: vec!["file_path".to_string()],
81 };
82 let context = create_test_context();
83
84 let result = ConditionEvaluator::evaluate(&condition, &context).unwrap();
85
86 assert!(result);
87 }
88
89 #[test]
90 fn test_evaluate_condition_with_missing_context_key() {
91 let condition = Condition {
92 expression: "missing_key == 'value'".to_string(),
93 context_keys: vec!["missing_key".to_string()],
94 };
95 let context = create_test_context();
96
97 let result = ConditionEvaluator::evaluate(&condition, &context);
98
99 assert!(result.is_err());
100 }
101
102 #[test]
103 fn test_evaluate_condition_with_metadata_key() {
104 let condition = Condition {
105 expression: "user == 'alice'".to_string(),
106 context_keys: vec!["user".to_string()],
107 };
108 let context = create_test_context();
109
110 let result = ConditionEvaluator::evaluate(&condition, &context).unwrap();
111
112 assert!(result);
113 }
114
115 #[test]
116 fn test_evaluate_condition_with_multiple_keys() {
117 let condition = Condition {
118 expression: "file_path.ends_with('.rs') && user == 'alice'".to_string(),
119 context_keys: vec!["file_path".to_string(), "user".to_string()],
120 };
121 let context = create_test_context();
122
123 let result = ConditionEvaluator::evaluate(&condition, &context).unwrap();
124
125 assert!(result);
126 }
127}