1pub type Result<T> = std::result::Result<T, PolicyError>;
5
6#[derive(Debug, thiserror::Error)]
8pub enum PolicyError {
9 #[error("circuit breaker open")]
11 CircuitOpen,
12
13 #[error("quality gate failed: {0}")]
15 GateFailed(String),
16
17 #[error("resource limit error: {0}")]
19 ResourceLimit(String),
20
21 #[error("jidoka violation: {0}")]
23 JidokaViolation(String),
24
25 #[error("I/O error: {0}")]
27 Io(#[from] std::io::Error),
28}
29
30impl PolicyError {
31 #[must_use]
33 pub fn gate_failed(msg: impl Into<String>) -> Self {
34 Self::GateFailed(msg.into())
35 }
36
37 #[must_use]
39 pub fn jidoka_violation(msg: impl Into<String>) -> Self {
40 Self::JidokaViolation(msg.into())
41 }
42}
43
44#[cfg(test)]
45mod tests {
46 use super::*;
47
48 #[test]
49 fn test_circuit_open_error() {
50 let err = PolicyError::CircuitOpen;
51 assert!(err.to_string().contains("circuit breaker open"));
52 }
53
54 #[test]
55 fn test_gate_failed_error() {
56 let err = PolicyError::gate_failed("complexity threshold exceeded");
57 assert!(err.to_string().contains("quality gate failed"));
58 assert!(err.to_string().contains("complexity"));
59 }
60
61 #[test]
62 fn test_jidoka_violation_error() {
63 let err = PolicyError::jidoka_violation("invariant violated");
64 assert!(err.to_string().contains("jidoka violation"));
65 assert!(err.to_string().contains("invariant"));
66 }
67
68 #[test]
69 fn test_resource_limit_error() {
70 let err = PolicyError::ResourceLimit("memory exceeded".into());
71 assert!(err.to_string().contains("resource limit"));
72 }
73
74 #[test]
75 fn test_io_error_conversion() {
76 let io_err = std::io::Error::new(std::io::ErrorKind::PermissionDenied, "access denied");
77 let err: PolicyError = io_err.into();
78 assert!(err.to_string().contains("I/O error"));
79 }
80}