1use std::fmt;
4use std::str::FromStr;
5
6use serde::{Deserialize, Deserializer, Serialize};
7
8#[derive(Debug, Clone, PartialEq, Eq)]
9pub struct UnknownAtmErrorCode(pub String);
10
11impl fmt::Display for UnknownAtmErrorCode {
12 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13 write!(f, "unknown ATM error code: {}", self.0)
14 }
15}
16
17impl std::error::Error for UnknownAtmErrorCode {}
18
19#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
20pub enum AtmErrorCode {
21 ConfigHomeUnavailable,
22 ConfigParseFailed,
23 ConfigRetiredHookMembersKey,
24 ConfigRetiredLegacyHookKeys,
25 ConfigTeamParseFailed,
26 ConfigTeamMissing,
27 IdentityUnavailable,
28 IdentityConflict,
29 DaemonUnavailable,
30 DaemonMayHaveExecuted,
31 DaemonLifecycleWedge,
32 DaemonLaunchGateRejected,
33 DaemonServingStateRejected,
34 DaemonStaleOwnerRecoveryFailed,
35 DaemonAutoStartFailed,
36 DaemonAdvisorySessionAlreadyRegistered,
37 DaemonAdvisorySessionNotRegistered,
38 RemoteDeliveryOutcomeUnknown,
39 AddressParseFailed,
40 TeamUnavailable,
41 TeamNotFound,
42 AgentNotFound,
43 MailboxReadFailed,
44 MailboxRecoveredMessageSetTooLarge,
45 MailboxWriteFailed,
46 MailboxLockFailed,
47 MailboxLockReadOnlyFilesystem,
48 MailboxLockTimeout,
49 InternalError,
50 MessageValidationFailed,
51 SerializationFailed,
52 FilePolicyRejected,
53 FileReferenceRewriteFailed,
54 WaitTimeout,
55 AckInvalidState,
56 ClearInvalidState,
57 ObservabilityEmitFailed,
58 ObservabilityQueryFailed,
59 ObservabilityFollowFailed,
60 ObservabilityHealthFailed,
61 ObservabilityBootstrapFailed,
62 ObservabilityHealthOk,
63 WarningInvalidTeamMemberSkipped,
64 WarningMailboxRecordSkipped,
65 WarningMalformedAtmFieldIgnored,
66 WarningObservabilityHealthDegraded,
67 WarningSqliteHealthDegraded,
68 WarningOriginInboxEntrySkipped,
69 WarningMissingTeamConfigFallback,
70 WarningSendAlertStateDegraded,
71 WarningIdentityDrift,
72 WarningRosterDrift,
73 WarningBaselineMemberMissing,
74 WarningRestoreInProgress,
75 WarningStaleMailboxLock,
76 WarningHookSkipped,
77 WarningHookExecutionFailed,
78 TestFakeTransportInjectionFailed,
79 HelpTopicNotFound,
80}
81
82impl AtmErrorCode {
83 pub const fn as_str(self) -> &'static str {
84 match self {
85 Self::ConfigHomeUnavailable => "ATM_CONFIG_HOME_UNAVAILABLE",
86 Self::ConfigParseFailed => "ATM_CONFIG_PARSE_FAILED",
87 Self::ConfigRetiredHookMembersKey => "ATM_CONFIG_RETIRED_HOOK_MEMBERS_KEY",
88 Self::ConfigRetiredLegacyHookKeys => "ATM_CONFIG_RETIRED_LEGACY_HOOK_KEYS",
89 Self::ConfigTeamParseFailed => "ATM_CONFIG_TEAM_PARSE_FAILED",
90 Self::ConfigTeamMissing => "ATM_CONFIG_TEAM_MISSING",
91 Self::IdentityUnavailable => "ATM_IDENTITY_UNAVAILABLE",
92 Self::IdentityConflict => "ATM_IDENTITY_CONFLICT",
93 Self::DaemonUnavailable => "ATM_DAEMON_UNAVAILABLE",
94 Self::DaemonMayHaveExecuted => "ATM_DAEMON_MAY_HAVE_EXECUTED",
95 Self::DaemonLifecycleWedge => "ATM_DAEMON_LIFECYCLE_WEDGE",
96 Self::DaemonLaunchGateRejected => "ATM_DAEMON_LAUNCH_GATE_REJECTED",
97 Self::DaemonServingStateRejected => "ATM_DAEMON_SERVING_STATE_REJECTED",
98 Self::DaemonStaleOwnerRecoveryFailed => "ATM_DAEMON_STALE_OWNER_RECOVERY_FAILED",
99 Self::DaemonAutoStartFailed => "ATM_DAEMON_AUTO_START_FAILED",
100 Self::DaemonAdvisorySessionAlreadyRegistered => {
101 "ATM_DAEMON_ADVISORY_SESSION_ALREADY_REGISTERED"
102 }
103 Self::DaemonAdvisorySessionNotRegistered => {
104 "ATM_DAEMON_ADVISORY_SESSION_NOT_REGISTERED"
105 }
106 Self::RemoteDeliveryOutcomeUnknown => "ATM_REMOTE_OUTCOME_UNKNOWN",
107 Self::AddressParseFailed => "ATM_ADDRESS_PARSE_FAILED",
108 Self::TeamUnavailable => "ATM_TEAM_UNAVAILABLE",
109 Self::TeamNotFound => "ATM_TEAM_NOT_FOUND",
110 Self::AgentNotFound => "ATM_AGENT_NOT_FOUND",
111 Self::MailboxReadFailed => "ATM_MAILBOX_READ_FAILED",
112 Self::MailboxRecoveredMessageSetTooLarge => {
113 "ATM_MAILBOX_RECOVERED_MESSAGE_SET_TOO_LARGE"
114 }
115 Self::MailboxWriteFailed => "ATM_MAILBOX_WRITE_FAILED",
116 Self::MailboxLockFailed => "ATM_MAILBOX_LOCK_FAILED",
117 Self::MailboxLockReadOnlyFilesystem => "ATM_MAILBOX_LOCK_READ_ONLY_FILESYSTEM",
118 Self::MailboxLockTimeout => "ATM_MAILBOX_LOCK_TIMEOUT",
119 Self::InternalError => "ATM_INTERNAL_ERROR",
120 Self::MessageValidationFailed => "ATM_MESSAGE_VALIDATION_FAILED",
121 Self::SerializationFailed => "ATM_SERIALIZATION_FAILED",
122 Self::FilePolicyRejected => "ATM_FILE_POLICY_REJECTED",
123 Self::FileReferenceRewriteFailed => "ATM_FILE_REFERENCE_REWRITE_FAILED",
124 Self::WaitTimeout => "ATM_WAIT_TIMEOUT",
125 Self::AckInvalidState => "ATM_ACK_INVALID_STATE",
126 Self::ClearInvalidState => "ATM_CLEAR_INVALID_STATE",
127 Self::ObservabilityEmitFailed => "ATM_OBSERVABILITY_EMIT_FAILED",
128 Self::ObservabilityQueryFailed => "ATM_OBSERVABILITY_QUERY_FAILED",
129 Self::ObservabilityFollowFailed => "ATM_OBSERVABILITY_FOLLOW_FAILED",
130 Self::ObservabilityHealthFailed => "ATM_OBSERVABILITY_HEALTH_FAILED",
131 Self::ObservabilityBootstrapFailed => "ATM_OBSERVABILITY_BOOTSTRAP_FAILED",
132 Self::ObservabilityHealthOk => "ATM_OBSERVABILITY_HEALTH_OK",
133 Self::WarningInvalidTeamMemberSkipped => "ATM_WARNING_INVALID_TEAM_MEMBER_SKIPPED",
134 Self::WarningMailboxRecordSkipped => "ATM_WARNING_MAILBOX_RECORD_SKIPPED",
135 Self::WarningMalformedAtmFieldIgnored => "ATM_WARNING_MALFORMED_ATM_FIELD_IGNORED",
136 Self::WarningObservabilityHealthDegraded => "ATM_WARNING_OBSERVABILITY_HEALTH_DEGRADED",
137 Self::WarningSqliteHealthDegraded => "ATM_WARNING_SQLITE_HEALTH_DEGRADED",
138 Self::WarningOriginInboxEntrySkipped => "ATM_WARNING_ORIGIN_INBOX_ENTRY_SKIPPED",
139 Self::WarningMissingTeamConfigFallback => "ATM_WARNING_MISSING_TEAM_CONFIG_FALLBACK",
140 Self::WarningSendAlertStateDegraded => "ATM_WARNING_SEND_ALERT_STATE_DEGRADED",
141 Self::WarningIdentityDrift => "ATM_WARNING_IDENTITY_DRIFT",
142 Self::WarningRosterDrift => "ATM_WARNING_ROSTER_DRIFT",
143 Self::WarningBaselineMemberMissing => "ATM_WARNING_BASELINE_MEMBER_MISSING",
144 Self::WarningRestoreInProgress => "ATM_WARNING_RESTORE_IN_PROGRESS",
145 Self::WarningStaleMailboxLock => "ATM_WARNING_STALE_MAILBOX_LOCK",
146 Self::WarningHookSkipped => "ATM_WARNING_HOOK_SKIPPED",
147 Self::WarningHookExecutionFailed => "ATM_WARNING_HOOK_EXECUTION_FAILED",
148 Self::TestFakeTransportInjectionFailed => "ATM_TEST_FAKE_TRANSPORT_INJECTION_FAILED",
149 Self::HelpTopicNotFound => "ATM_HELP_TOPIC_NOT_FOUND",
150 }
151 }
152}
153
154impl FromStr for AtmErrorCode {
155 type Err = UnknownAtmErrorCode;
156
157 fn from_str(value: &str) -> Result<Self, Self::Err> {
158 match value {
159 "ATM_CONFIG_HOME_UNAVAILABLE" => Ok(Self::ConfigHomeUnavailable),
160 "ATM_CONFIG_PARSE_FAILED" => Ok(Self::ConfigParseFailed),
161 "ATM_CONFIG_RETIRED_HOOK_MEMBERS_KEY" => Ok(Self::ConfigRetiredHookMembersKey),
162 "ATM_CONFIG_RETIRED_LEGACY_HOOK_KEYS" => Ok(Self::ConfigRetiredLegacyHookKeys),
163 "ATM_CONFIG_TEAM_PARSE_FAILED" => Ok(Self::ConfigTeamParseFailed),
164 "ATM_CONFIG_TEAM_MISSING" => Ok(Self::ConfigTeamMissing),
165 "ATM_IDENTITY_UNAVAILABLE" => Ok(Self::IdentityUnavailable),
166 "ATM_IDENTITY_CONFLICT" => Ok(Self::IdentityConflict),
167 "ATM_DAEMON_UNAVAILABLE" => Ok(Self::DaemonUnavailable),
168 "ATM_DAEMON_MAY_HAVE_EXECUTED" => Ok(Self::DaemonMayHaveExecuted),
169 "ATM_DAEMON_LIFECYCLE_WEDGE" => Ok(Self::DaemonLifecycleWedge),
170 "ATM_DAEMON_LAUNCH_GATE_REJECTED" => Ok(Self::DaemonLaunchGateRejected),
171 "ATM_DAEMON_SERVING_STATE_REJECTED" => Ok(Self::DaemonServingStateRejected),
172 "ATM_DAEMON_STALE_OWNER_RECOVERY_FAILED" => Ok(Self::DaemonStaleOwnerRecoveryFailed),
173 "ATM_DAEMON_AUTO_START_FAILED" => Ok(Self::DaemonAutoStartFailed),
174 "ATM_DAEMON_ADVISORY_SESSION_ALREADY_REGISTERED" => {
175 Ok(Self::DaemonAdvisorySessionAlreadyRegistered)
176 }
177 "ATM_DAEMON_ADVISORY_SESSION_NOT_REGISTERED" => {
178 Ok(Self::DaemonAdvisorySessionNotRegistered)
179 }
180 "ATM_REMOTE_OUTCOME_UNKNOWN" => Ok(Self::RemoteDeliveryOutcomeUnknown),
181 "ATM_ADDRESS_PARSE_FAILED" => Ok(Self::AddressParseFailed),
182 "ATM_TEAM_UNAVAILABLE" => Ok(Self::TeamUnavailable),
183 "ATM_TEAM_NOT_FOUND" => Ok(Self::TeamNotFound),
184 "ATM_AGENT_NOT_FOUND" => Ok(Self::AgentNotFound),
185 "ATM_MAILBOX_READ_FAILED" => Ok(Self::MailboxReadFailed),
186 "ATM_MAILBOX_RECOVERED_MESSAGE_SET_TOO_LARGE" => {
187 Ok(Self::MailboxRecoveredMessageSetTooLarge)
188 }
189 "ATM_MAILBOX_WRITE_FAILED" => Ok(Self::MailboxWriteFailed),
190 "ATM_MAILBOX_LOCK_FAILED" => Ok(Self::MailboxLockFailed),
191 "ATM_MAILBOX_LOCK_READ_ONLY_FILESYSTEM" => Ok(Self::MailboxLockReadOnlyFilesystem),
192 "ATM_MAILBOX_LOCK_TIMEOUT" => Ok(Self::MailboxLockTimeout),
193 "ATM_INTERNAL_ERROR" => Ok(Self::InternalError),
194 "ATM_MESSAGE_VALIDATION_FAILED" => Ok(Self::MessageValidationFailed),
195 "ATM_SERIALIZATION_FAILED" => Ok(Self::SerializationFailed),
196 "ATM_FILE_POLICY_REJECTED" => Ok(Self::FilePolicyRejected),
197 "ATM_FILE_REFERENCE_REWRITE_FAILED" => Ok(Self::FileReferenceRewriteFailed),
198 "ATM_WAIT_TIMEOUT" => Ok(Self::WaitTimeout),
199 "ATM_ACK_INVALID_STATE" => Ok(Self::AckInvalidState),
200 "ATM_CLEAR_INVALID_STATE" => Ok(Self::ClearInvalidState),
201 "ATM_OBSERVABILITY_EMIT_FAILED" => Ok(Self::ObservabilityEmitFailed),
202 "ATM_OBSERVABILITY_QUERY_FAILED" => Ok(Self::ObservabilityQueryFailed),
203 "ATM_OBSERVABILITY_FOLLOW_FAILED" => Ok(Self::ObservabilityFollowFailed),
204 "ATM_OBSERVABILITY_HEALTH_FAILED" => Ok(Self::ObservabilityHealthFailed),
205 "ATM_OBSERVABILITY_BOOTSTRAP_FAILED" => Ok(Self::ObservabilityBootstrapFailed),
206 "ATM_OBSERVABILITY_HEALTH_OK" => Ok(Self::ObservabilityHealthOk),
207 "ATM_WARNING_INVALID_TEAM_MEMBER_SKIPPED" => Ok(Self::WarningInvalidTeamMemberSkipped),
208 "ATM_WARNING_MAILBOX_RECORD_SKIPPED" => Ok(Self::WarningMailboxRecordSkipped),
209 "ATM_WARNING_MALFORMED_ATM_FIELD_IGNORED" => Ok(Self::WarningMalformedAtmFieldIgnored),
210 "ATM_WARNING_OBSERVABILITY_HEALTH_DEGRADED" => {
211 Ok(Self::WarningObservabilityHealthDegraded)
212 }
213 "ATM_WARNING_SQLITE_HEALTH_DEGRADED" => Ok(Self::WarningSqliteHealthDegraded),
214 "ATM_WARNING_ORIGIN_INBOX_ENTRY_SKIPPED" => Ok(Self::WarningOriginInboxEntrySkipped),
215 "ATM_WARNING_MISSING_TEAM_CONFIG_FALLBACK" => {
216 Ok(Self::WarningMissingTeamConfigFallback)
217 }
218 "ATM_WARNING_SEND_ALERT_STATE_DEGRADED" => Ok(Self::WarningSendAlertStateDegraded),
219 "ATM_WARNING_IDENTITY_DRIFT" => Ok(Self::WarningIdentityDrift),
220 "ATM_WARNING_ROSTER_DRIFT" => Ok(Self::WarningRosterDrift),
221 "ATM_WARNING_BASELINE_MEMBER_MISSING" => Ok(Self::WarningBaselineMemberMissing),
222 "ATM_WARNING_RESTORE_IN_PROGRESS" => Ok(Self::WarningRestoreInProgress),
223 "ATM_WARNING_STALE_MAILBOX_LOCK" => Ok(Self::WarningStaleMailboxLock),
224 "ATM_WARNING_HOOK_SKIPPED" => Ok(Self::WarningHookSkipped),
225 "ATM_WARNING_HOOK_EXECUTION_FAILED" => Ok(Self::WarningHookExecutionFailed),
226 "ATM_TEST_FAKE_TRANSPORT_INJECTION_FAILED" => {
227 Ok(Self::TestFakeTransportInjectionFailed)
228 }
229 "ATM_HELP_TOPIC_NOT_FOUND" => Ok(Self::HelpTopicNotFound),
230 _ => Err(UnknownAtmErrorCode(value.to_owned())),
231 }
232 }
233}
234
235impl fmt::Display for AtmErrorCode {
236 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
237 f.write_str(self.as_str())
238 }
239}
240
241impl Serialize for AtmErrorCode {
242 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
243 where
244 S: serde::Serializer,
245 {
246 serializer.serialize_str(self.as_str())
247 }
248}
249
250impl<'de> Deserialize<'de> for AtmErrorCode {
251 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
252 where
253 D: Deserializer<'de>,
254 {
255 let value = String::deserialize(deserializer)?;
256 value.parse().map_err(serde::de::Error::custom)
257 }
258}