#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum TransportKind {
Kafka,
Grpc,
Memory,
File,
Pipe,
Http,
Redis,
Routed,
}
impl TransportKind {
#[must_use]
pub const fn as_label(self) -> &'static str {
match self {
Self::Kafka => "kafka",
Self::Grpc => "grpc",
Self::Memory => "memory",
Self::File => "file",
Self::Pipe => "pipe",
Self::Http => "http",
Self::Redis => "redis",
Self::Routed => "routed",
}
}
}
impl std::fmt::Display for TransportKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_label())
}
}
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum FlushTrigger {
Size,
Records,
Age,
Eviction,
Shutdown,
Manual,
}
impl FlushTrigger {
#[must_use]
pub const fn as_label(self) -> &'static str {
match self {
Self::Size => "size",
Self::Records => "records",
Self::Age => "age",
Self::Eviction => "eviction",
Self::Shutdown => "shutdown",
Self::Manual => "manual",
}
}
}
impl std::fmt::Display for FlushTrigger {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_label())
}
}
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum AuthFailureReason {
Expired,
InvalidSignature,
InvalidClient,
InvalidGrant,
InvalidScope,
MalformedToken,
RevokedToken,
RateLimited,
Unauthorized,
AccessDenied,
}
impl AuthFailureReason {
#[must_use]
pub const fn as_label(self) -> &'static str {
match self {
Self::Expired => "expired",
Self::InvalidSignature => "invalid_signature",
Self::InvalidClient => "invalid_client",
Self::InvalidGrant => "invalid_grant",
Self::InvalidScope => "invalid_scope",
Self::MalformedToken => "malformed_token",
Self::RevokedToken => "revoked_token",
Self::RateLimited => "rate_limited",
Self::Unauthorized => "unauthorized",
Self::AccessDenied => "access_denied",
}
}
}
impl std::fmt::Display for AuthFailureReason {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_label())
}
}
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ValidationFailureReason {
SchemaInvalid,
FieldMissing,
TypeMismatch,
OutOfRange,
PatternMismatch,
FormatInvalid,
EnumViolation,
AdditionalProperties,
NullValue,
EncodingError,
}
impl ValidationFailureReason {
#[must_use]
pub const fn as_label(self) -> &'static str {
match self {
Self::SchemaInvalid => "schema_invalid",
Self::FieldMissing => "field_missing",
Self::TypeMismatch => "type_mismatch",
Self::OutOfRange => "out_of_range",
Self::PatternMismatch => "pattern_mismatch",
Self::FormatInvalid => "format_invalid",
Self::EnumViolation => "enum_violation",
Self::AdditionalProperties => "additional_properties",
Self::NullValue => "null_value",
Self::EncodingError => "encoding_error",
}
}
}
impl std::fmt::Display for ValidationFailureReason {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_label())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn label_values_are_snake_case_ascii() {
let all: &[&str] = &[
TransportKind::Kafka.as_label(),
TransportKind::Grpc.as_label(),
TransportKind::Memory.as_label(),
TransportKind::File.as_label(),
TransportKind::Pipe.as_label(),
TransportKind::Http.as_label(),
TransportKind::Redis.as_label(),
TransportKind::Routed.as_label(),
FlushTrigger::Size.as_label(),
FlushTrigger::Records.as_label(),
FlushTrigger::Age.as_label(),
FlushTrigger::Eviction.as_label(),
FlushTrigger::Shutdown.as_label(),
FlushTrigger::Manual.as_label(),
AuthFailureReason::Expired.as_label(),
AuthFailureReason::InvalidSignature.as_label(),
AuthFailureReason::InvalidClient.as_label(),
AuthFailureReason::InvalidGrant.as_label(),
AuthFailureReason::InvalidScope.as_label(),
AuthFailureReason::MalformedToken.as_label(),
AuthFailureReason::RevokedToken.as_label(),
AuthFailureReason::RateLimited.as_label(),
AuthFailureReason::Unauthorized.as_label(),
AuthFailureReason::AccessDenied.as_label(),
ValidationFailureReason::SchemaInvalid.as_label(),
ValidationFailureReason::FieldMissing.as_label(),
ValidationFailureReason::TypeMismatch.as_label(),
ValidationFailureReason::OutOfRange.as_label(),
ValidationFailureReason::PatternMismatch.as_label(),
ValidationFailureReason::FormatInvalid.as_label(),
ValidationFailureReason::EnumViolation.as_label(),
ValidationFailureReason::AdditionalProperties.as_label(),
ValidationFailureReason::NullValue.as_label(),
ValidationFailureReason::EncodingError.as_label(),
];
for s in all {
assert!(
s.bytes()
.all(|b| b.is_ascii_lowercase() || b == b'_' || b.is_ascii_digit()),
"non-snake-case label: {s:?}"
);
assert!(!s.is_empty(), "empty label");
}
}
}