av_sandbox/
denial_code.rs1use serde::{Deserialize, Serialize};
9use std::fmt;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
13#[non_exhaustive]
14pub enum DenialCode {
15 #[serde(rename = "PARSE_ERROR")]
17 ParseError,
18 #[serde(rename = "PASSTHROUGH_REFUSED")]
21 PassthroughRefused,
22 #[serde(rename = "SCHEMA_VIOLATION")]
24 SchemaViolation,
25 #[serde(rename = "SCHEMA_MISSING")]
27 SchemaMissing,
28 #[serde(rename = "POLICY_DENIED")]
30 PolicyDenied,
31 #[serde(rename = "BUDGET_EXCEEDED")]
33 BudgetExceeded,
34 #[serde(rename = "BUDGET_ERROR")]
36 BudgetError,
37 #[serde(rename = "UNMAPPED_TOOL")]
39 UnmappedTool,
40 #[serde(rename = "MISSION_EXPIRED")]
42 MissionExpired,
43 #[serde(rename = "MISSION_DENIED")]
45 MissionDenied,
46 #[serde(rename = "SCOPE_INSUFFICIENT")]
48 ScopeInsufficient,
49 #[serde(rename = "TOKEN_REVOKED")]
51 TokenRevoked,
52 #[serde(rename = "NO_BACKEND")]
54 NoBackend,
55 #[serde(rename = "INTENT_TOKEN_ERROR")]
57 IntentTokenError,
58 #[serde(rename = "PAYOUT_INVALID")]
60 PayoutInvalid,
61 #[serde(rename = "PDP_DENIED")]
63 PdpDenied,
64}
65
66impl DenialCode {
67 pub fn as_str(self) -> &'static str {
69 match self {
70 Self::ParseError => "PARSE_ERROR",
71 Self::PassthroughRefused => "PASSTHROUGH_REFUSED",
72 Self::SchemaViolation => "SCHEMA_VIOLATION",
73 Self::SchemaMissing => "SCHEMA_MISSING",
74 Self::PolicyDenied => "POLICY_DENIED",
75 Self::BudgetExceeded => "BUDGET_EXCEEDED",
76 Self::BudgetError => "BUDGET_ERROR",
77 Self::UnmappedTool => "UNMAPPED_TOOL",
78 Self::MissionExpired => "MISSION_EXPIRED",
79 Self::MissionDenied => "MISSION_DENIED",
80 Self::ScopeInsufficient => "SCOPE_INSUFFICIENT",
81 Self::TokenRevoked => "TOKEN_REVOKED",
82 Self::NoBackend => "NO_BACKEND",
83 Self::IntentTokenError => "INTENT_TOKEN_ERROR",
84 Self::PayoutInvalid => "PAYOUT_INVALID",
85 Self::PdpDenied => "PDP_DENIED",
86 }
87 }
88}
89
90impl fmt::Display for DenialCode {
91 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
92 f.write_str(self.as_str())
93 }
94}
95
96#[cfg(test)]
97mod tests {
98 #![allow(clippy::unwrap_used)]
99
100 use super::*;
101
102 #[test]
103 fn as_str_round_trips_through_serde() {
104 let codes = [
105 DenialCode::ParseError,
106 DenialCode::PassthroughRefused,
107 DenialCode::SchemaViolation,
108 DenialCode::SchemaMissing,
109 DenialCode::PolicyDenied,
110 DenialCode::BudgetExceeded,
111 DenialCode::BudgetError,
112 DenialCode::UnmappedTool,
113 DenialCode::MissionExpired,
114 DenialCode::MissionDenied,
115 DenialCode::ScopeInsufficient,
116 DenialCode::TokenRevoked,
117 DenialCode::NoBackend,
118 DenialCode::IntentTokenError,
119 DenialCode::PayoutInvalid,
120 DenialCode::PdpDenied,
121 ];
122 for code in codes {
123 let json = serde_json::to_string(&code).unwrap();
124 let back: DenialCode = serde_json::from_str(&json).unwrap();
125 assert_eq!(back, code);
126 assert_eq!(format!("\"{code}\""), json);
127 }
128 }
129
130 #[test]
131 fn display_matches_as_str() {
132 for code in [DenialCode::UnmappedTool, DenialCode::MissionExpired] {
133 assert_eq!(format!("{code}"), code.as_str());
134 }
135 }
136}