1use thiserror::Error;
2
3#[non_exhaustive]
6#[derive(Debug, Error)]
7pub enum MacpError {
8 #[error("InvalidMacpVersion")]
9 InvalidMacpVersion,
10 #[error("InvalidEnvelope")]
11 InvalidEnvelope,
12 #[error("SessionAlreadyExists")]
13 SessionAlreadyExists,
14 #[error("UnknownSession")]
15 UnknownSession,
16 #[error("SessionNotOpen")]
17 SessionNotOpen,
18 #[error("TtlExpired")]
19 TtlExpired,
20 #[error("InvalidTtl")]
21 InvalidTtl,
22 #[error("UnknownMode")]
23 UnknownMode,
24 #[error("InvalidModeState")]
25 InvalidModeState,
26 #[error("InvalidPayload")]
27 InvalidPayload,
28 #[error("Forbidden")]
29 Forbidden,
30 #[error("Unauthenticated")]
31 Unauthenticated,
32 #[error("DuplicateMessage")]
36 DuplicateMessage,
37 #[error("PayloadTooLarge")]
38 PayloadTooLarge,
39 #[error("RateLimited")]
40 RateLimited,
41 #[error("StorageFailed")]
42 StorageFailed,
43 #[error("InvalidSessionId")]
44 InvalidSessionId,
45 #[error("UnknownPolicyVersion")]
46 UnknownPolicyVersion,
47 #[error("PolicyDenied")]
48 PolicyDenied { reasons: Vec<String> },
49 #[error("InvalidPolicyDefinition")]
50 InvalidPolicyDefinition,
51}
52
53impl MacpError {
54 pub fn error_code(&self) -> &'static str {
56 match self {
57 MacpError::InvalidMacpVersion => "UNSUPPORTED_PROTOCOL_VERSION",
58 MacpError::InvalidEnvelope => "INVALID_ENVELOPE",
59 MacpError::SessionAlreadyExists => "SESSION_ALREADY_EXISTS",
60 MacpError::UnknownSession => "SESSION_NOT_FOUND",
61 MacpError::SessionNotOpen => "SESSION_NOT_OPEN",
62 MacpError::TtlExpired => "SESSION_NOT_OPEN",
63 MacpError::InvalidTtl => "INVALID_ENVELOPE",
64 MacpError::UnknownMode => "MODE_NOT_SUPPORTED",
65 MacpError::InvalidModeState => "INVALID_ENVELOPE",
66 MacpError::InvalidPayload => "INVALID_ENVELOPE",
67 MacpError::Forbidden => "FORBIDDEN",
68 MacpError::Unauthenticated => "UNAUTHENTICATED",
69 MacpError::DuplicateMessage => "DUPLICATE_MESSAGE",
70 MacpError::PayloadTooLarge => "PAYLOAD_TOO_LARGE",
71 MacpError::RateLimited => "RATE_LIMITED",
72 MacpError::StorageFailed => "INTERNAL_ERROR",
73 MacpError::InvalidSessionId => "INVALID_SESSION_ID",
74 MacpError::UnknownPolicyVersion => "UNKNOWN_POLICY_VERSION",
75 MacpError::PolicyDenied { .. } => "POLICY_DENIED",
76 MacpError::InvalidPolicyDefinition => "INVALID_POLICY_DEFINITION",
77 }
78 }
79}
80
81#[cfg(test)]
82mod tests {
83 use super::*;
84
85 #[test]
86 fn error_code_mapping_covers_all_variants() {
87 let cases: Vec<(MacpError, &str)> = vec![
88 (
89 MacpError::InvalidMacpVersion,
90 "UNSUPPORTED_PROTOCOL_VERSION",
91 ),
92 (MacpError::InvalidEnvelope, "INVALID_ENVELOPE"),
93 (MacpError::SessionAlreadyExists, "SESSION_ALREADY_EXISTS"),
94 (MacpError::UnknownSession, "SESSION_NOT_FOUND"),
95 (MacpError::SessionNotOpen, "SESSION_NOT_OPEN"),
96 (MacpError::TtlExpired, "SESSION_NOT_OPEN"),
97 (MacpError::InvalidTtl, "INVALID_ENVELOPE"),
98 (MacpError::UnknownMode, "MODE_NOT_SUPPORTED"),
99 (MacpError::InvalidModeState, "INVALID_ENVELOPE"),
100 (MacpError::InvalidPayload, "INVALID_ENVELOPE"),
101 (MacpError::Forbidden, "FORBIDDEN"),
102 (MacpError::Unauthenticated, "UNAUTHENTICATED"),
103 (MacpError::DuplicateMessage, "DUPLICATE_MESSAGE"),
104 (MacpError::PayloadTooLarge, "PAYLOAD_TOO_LARGE"),
105 (MacpError::RateLimited, "RATE_LIMITED"),
106 (MacpError::StorageFailed, "INTERNAL_ERROR"),
107 (MacpError::InvalidSessionId, "INVALID_SESSION_ID"),
108 (MacpError::UnknownPolicyVersion, "UNKNOWN_POLICY_VERSION"),
109 (
110 MacpError::PolicyDenied {
111 reasons: vec!["test".into()],
112 },
113 "POLICY_DENIED",
114 ),
115 (
116 MacpError::InvalidPolicyDefinition,
117 "INVALID_POLICY_DEFINITION",
118 ),
119 ];
120
121 for (error, expected_code) in cases {
122 assert_eq!(
123 error.error_code(),
124 expected_code,
125 "error_code() mismatch for {:?}",
126 error
127 );
128 assert!(!error.to_string().is_empty());
129 }
130 }
131
132 #[test]
133 fn display_matches_variant_name() {
134 assert_eq!(
135 MacpError::InvalidMacpVersion.to_string(),
136 "InvalidMacpVersion"
137 );
138 assert_eq!(MacpError::Forbidden.to_string(), "Forbidden");
139 assert_eq!(MacpError::TtlExpired.to_string(), "TtlExpired");
140 assert_eq!(MacpError::Unauthenticated.to_string(), "Unauthenticated");
141 assert_eq!(MacpError::DuplicateMessage.to_string(), "DuplicateMessage");
142 assert_eq!(MacpError::PayloadTooLarge.to_string(), "PayloadTooLarge");
143 assert_eq!(MacpError::RateLimited.to_string(), "RateLimited");
144 assert_eq!(MacpError::StorageFailed.to_string(), "StorageFailed");
145 assert_eq!(MacpError::InvalidSessionId.to_string(), "InvalidSessionId");
146 assert_eq!(
147 MacpError::UnknownPolicyVersion.to_string(),
148 "UnknownPolicyVersion"
149 );
150 assert_eq!(
151 MacpError::PolicyDenied {
152 reasons: vec!["test".into()]
153 }
154 .to_string(),
155 "PolicyDenied"
156 );
157 }
158}