agentic_contract/
condition.rs1use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
5
6use crate::ContractId;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
10#[serde(rename_all = "snake_case")]
11pub enum ConditionType {
12 Threshold,
14 TimeBased,
16 Dependency,
18 Custom,
20}
21
22#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
24#[serde(rename_all = "snake_case")]
25pub enum ConditionStatus {
26 Unevaluated,
28 Met,
30 NotMet,
32 Unknown,
34}
35
36#[derive(Debug, Clone, Serialize, Deserialize)]
38pub struct Condition {
39 pub id: ContractId,
41 pub label: String,
43 pub condition_type: ConditionType,
45 pub expression: String,
47 pub status: ConditionStatus,
49 #[serde(default)]
51 pub last_result: Option<String>,
52 pub created_at: DateTime<Utc>,
54 #[serde(skip_serializing_if = "Option::is_none")]
56 pub evaluated_at: Option<DateTime<Utc>>,
57}
58
59impl Condition {
60 pub fn new(
62 label: impl Into<String>,
63 condition_type: ConditionType,
64 expression: impl Into<String>,
65 ) -> Self {
66 Self {
67 id: ContractId::new(),
68 label: label.into(),
69 condition_type,
70 expression: expression.into(),
71 status: ConditionStatus::Unevaluated,
72 last_result: None,
73 created_at: Utc::now(),
74 evaluated_at: None,
75 }
76 }
77
78 pub fn mark_met(&mut self, message: impl Into<String>) {
80 self.status = ConditionStatus::Met;
81 self.last_result = Some(message.into());
82 self.evaluated_at = Some(Utc::now());
83 }
84
85 pub fn mark_not_met(&mut self, message: impl Into<String>) {
87 self.status = ConditionStatus::NotMet;
88 self.last_result = Some(message.into());
89 self.evaluated_at = Some(Utc::now());
90 }
91
92 pub fn is_met(&self) -> bool {
94 self.status == ConditionStatus::Met
95 }
96}
97
98#[cfg(test)]
99mod tests {
100 use super::*;
101
102 #[test]
103 fn test_condition_lifecycle() {
104 let mut condition = Condition::new(
105 "CPU below 80%",
106 ConditionType::Threshold,
107 "system.cpu_usage < 0.8",
108 );
109
110 assert_eq!(condition.status, ConditionStatus::Unevaluated);
111 assert!(!condition.is_met());
112
113 condition.mark_met("CPU at 65%");
114 assert!(condition.is_met());
115 assert!(condition.evaluated_at.is_some());
116 }
117}