1#[non_exhaustive]
35#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
36pub enum TransportKind {
37 Kafka,
38 Grpc,
39 Memory,
40 File,
41 Pipe,
42 Http,
43 Redis,
44 Routed,
45}
46
47impl TransportKind {
48 #[must_use]
50 pub const fn as_label(self) -> &'static str {
51 match self {
52 Self::Kafka => "kafka",
53 Self::Grpc => "grpc",
54 Self::Memory => "memory",
55 Self::File => "file",
56 Self::Pipe => "pipe",
57 Self::Http => "http",
58 Self::Redis => "redis",
59 Self::Routed => "routed",
60 }
61 }
62}
63
64impl std::fmt::Display for TransportKind {
65 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
66 f.write_str(self.as_label())
67 }
68}
69
70#[non_exhaustive]
73#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
74pub enum FlushTrigger {
75 Size,
77 Records,
79 Age,
81 Eviction,
83 Shutdown,
85 Manual,
87}
88
89impl FlushTrigger {
90 #[must_use]
91 pub const fn as_label(self) -> &'static str {
92 match self {
93 Self::Size => "size",
94 Self::Records => "records",
95 Self::Age => "age",
96 Self::Eviction => "eviction",
97 Self::Shutdown => "shutdown",
98 Self::Manual => "manual",
99 }
100 }
101}
102
103impl std::fmt::Display for FlushTrigger {
104 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
105 f.write_str(self.as_label())
106 }
107}
108
109#[non_exhaustive]
115#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
116pub enum AuthFailureReason {
117 Expired,
119 InvalidSignature,
121 InvalidClient,
123 InvalidGrant,
125 InvalidScope,
127 MalformedToken,
129 RevokedToken,
131 RateLimited,
133 Unauthorized,
135 AccessDenied,
137}
138
139impl AuthFailureReason {
140 #[must_use]
141 pub const fn as_label(self) -> &'static str {
142 match self {
143 Self::Expired => "expired",
144 Self::InvalidSignature => "invalid_signature",
145 Self::InvalidClient => "invalid_client",
146 Self::InvalidGrant => "invalid_grant",
147 Self::InvalidScope => "invalid_scope",
148 Self::MalformedToken => "malformed_token",
149 Self::RevokedToken => "revoked_token",
150 Self::RateLimited => "rate_limited",
151 Self::Unauthorized => "unauthorized",
152 Self::AccessDenied => "access_denied",
153 }
154 }
155}
156
157impl std::fmt::Display for AuthFailureReason {
158 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
159 f.write_str(self.as_label())
160 }
161}
162
163#[non_exhaustive]
167#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
168pub enum ValidationFailureReason {
169 SchemaInvalid,
171 FieldMissing,
173 TypeMismatch,
175 OutOfRange,
177 PatternMismatch,
179 FormatInvalid,
181 EnumViolation,
183 AdditionalProperties,
185 NullValue,
187 EncodingError,
189}
190
191impl ValidationFailureReason {
192 #[must_use]
193 pub const fn as_label(self) -> &'static str {
194 match self {
195 Self::SchemaInvalid => "schema_invalid",
196 Self::FieldMissing => "field_missing",
197 Self::TypeMismatch => "type_mismatch",
198 Self::OutOfRange => "out_of_range",
199 Self::PatternMismatch => "pattern_mismatch",
200 Self::FormatInvalid => "format_invalid",
201 Self::EnumViolation => "enum_violation",
202 Self::AdditionalProperties => "additional_properties",
203 Self::NullValue => "null_value",
204 Self::EncodingError => "encoding_error",
205 }
206 }
207}
208
209impl std::fmt::Display for ValidationFailureReason {
210 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
211 f.write_str(self.as_label())
212 }
213}
214
215#[cfg(test)]
216mod tests {
217 use super::*;
218
219 #[test]
223 fn label_values_are_snake_case_ascii() {
224 let all: &[&str] = &[
225 TransportKind::Kafka.as_label(),
226 TransportKind::Grpc.as_label(),
227 TransportKind::Memory.as_label(),
228 TransportKind::File.as_label(),
229 TransportKind::Pipe.as_label(),
230 TransportKind::Http.as_label(),
231 TransportKind::Redis.as_label(),
232 TransportKind::Routed.as_label(),
233 FlushTrigger::Size.as_label(),
234 FlushTrigger::Records.as_label(),
235 FlushTrigger::Age.as_label(),
236 FlushTrigger::Eviction.as_label(),
237 FlushTrigger::Shutdown.as_label(),
238 FlushTrigger::Manual.as_label(),
239 AuthFailureReason::Expired.as_label(),
240 AuthFailureReason::InvalidSignature.as_label(),
241 AuthFailureReason::InvalidClient.as_label(),
242 AuthFailureReason::InvalidGrant.as_label(),
243 AuthFailureReason::InvalidScope.as_label(),
244 AuthFailureReason::MalformedToken.as_label(),
245 AuthFailureReason::RevokedToken.as_label(),
246 AuthFailureReason::RateLimited.as_label(),
247 AuthFailureReason::Unauthorized.as_label(),
248 AuthFailureReason::AccessDenied.as_label(),
249 ValidationFailureReason::SchemaInvalid.as_label(),
250 ValidationFailureReason::FieldMissing.as_label(),
251 ValidationFailureReason::TypeMismatch.as_label(),
252 ValidationFailureReason::OutOfRange.as_label(),
253 ValidationFailureReason::PatternMismatch.as_label(),
254 ValidationFailureReason::FormatInvalid.as_label(),
255 ValidationFailureReason::EnumViolation.as_label(),
256 ValidationFailureReason::AdditionalProperties.as_label(),
257 ValidationFailureReason::NullValue.as_label(),
258 ValidationFailureReason::EncodingError.as_label(),
259 ];
260 for s in all {
261 assert!(
262 s.bytes()
263 .all(|b| b.is_ascii_lowercase() || b == b'_' || b.is_ascii_digit()),
264 "non-snake-case label: {s:?}"
265 );
266 assert!(!s.is_empty(), "empty label");
267 }
268 }
269}