1pub mod ast;
18pub mod compiler;
19pub mod error;
20pub mod parser;
21pub mod signature;
22
23use serde::{Deserialize, Serialize};
24
25pub const RULE_PREFIX: &str = "CRUE";
27pub const RULE_VERSION: &str = "1.0.0";
28
29#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
31#[serde(rename_all = "UPPERCASE")]
32pub enum Severity {
33 Critical,
35 #[default]
37 High,
38 Medium,
40 Low,
42}
43
44#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
46#[serde(rename_all = "UPPERCASE")]
47pub enum Action {
48 Block {
50 #[serde(rename = "code")]
51 error_code: String,
52 #[serde(rename = "message")]
53 error_message: Option<String>,
54 },
55 Warn {
57 #[serde(rename = "code")]
58 warning_code: String,
59 },
60 RequireApproval {
62 #[serde(rename = "code")]
63 approval_code: String,
64 #[serde(rename = "timeout_minutes")]
65 timeout: u32,
66 },
67 Log,
69 AlertSoc,
71}
72
73impl Default for Action {
74 fn default() -> Self {
75 Action::Block {
76 error_code: "UNKNOWN_ERROR".to_string(),
77 error_message: None,
78 }
79 }
80}
81
82#[derive(Debug, Clone, Serialize, Deserialize)]
84pub struct CompiledRule {
85 pub id: String,
87 pub version: String,
89 pub source_hash: String,
91 pub signature: Vec<u8>,
93 pub signer_key_id: String,
95 pub bytecode: Vec<u8>,
97 pub compiled_at: i64,
99 pub valid_from: Option<i64>,
101 pub valid_until: Option<i64>,
102}
103
104#[derive(Debug, Clone, Serialize, Deserialize)]
106pub struct RuleSource {
107 pub id: String,
109 pub version: String,
111 pub conditions: ast::Expression,
113 pub actions: Vec<Action>,
115 pub metadata: RuleMetadata,
117}
118
119#[derive(Debug, Clone, Serialize, Deserialize)]
121pub struct RuleMetadata {
122 pub name: String,
124 pub description: String,
126 pub severity: Severity,
128 pub category: String,
130 pub author: String,
132 pub created_at: String,
134 pub validated_by: Option<String>,
136}
137
138#[cfg(test)]
139mod tests {
140 use super::*;
141
142 #[test]
143 fn test_action_serialization() {
144 let action = Action::Block {
145 error_code: "VOLUME_EXCEEDED".to_string(),
146 error_message: Some("Quota dépassé".to_string()),
147 };
148
149 let json = serde_json::to_string(&action).unwrap();
150 assert!(json.contains("VOLUME_EXCEEDED"));
151 }
152
153 #[test]
154 fn test_severity_default() {
155 let severity: Severity = serde_json::from_str("\"HIGH\"").unwrap();
156 assert_eq!(severity, Severity::High);
157 }
158}