1use std::str::FromStr;
4
5use buffa::Enumeration;
6use serde::{Deserialize, Serialize};
7
8use crate::UnknownVariant;
9
10#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
17#[serde(rename_all = "snake_case")]
18#[repr(i32)]
19#[non_exhaustive]
20pub enum Tier {
21 #[default]
23 Unspecified = 0,
24 Log = 1,
26 Metric = 2,
28 Trace = 3,
30 Audit = 4,
32}
33
34impl Tier {
35 #[must_use]
38 pub const fn as_str(self) -> &'static str {
39 match self {
40 Self::Unspecified => "unspecified",
41 Self::Log => "log",
42 Self::Metric => "metric",
43 Self::Trace => "trace",
44 Self::Audit => "audit",
45 }
46 }
47}
48
49impl Enumeration for Tier {
50 fn from_i32(value: i32) -> Option<Self> {
51 match value {
52 0 => Some(Self::Unspecified),
53 1 => Some(Self::Log),
54 2 => Some(Self::Metric),
55 3 => Some(Self::Trace),
56 4 => Some(Self::Audit),
57 _ => None,
58 }
59 }
60
61 fn to_i32(&self) -> i32 {
62 *self as i32
63 }
64
65 fn proto_name(&self) -> &'static str {
66 match self {
67 Self::Unspecified => "TIER_UNSPECIFIED",
68 Self::Log => "TIER_LOG",
69 Self::Metric => "TIER_METRIC",
70 Self::Trace => "TIER_TRACE",
71 Self::Audit => "TIER_AUDIT",
72 }
73 }
74
75 fn from_proto_name(name: &str) -> Option<Self> {
76 match name {
77 "TIER_UNSPECIFIED" => Some(Self::Unspecified),
78 "TIER_LOG" => Some(Self::Log),
79 "TIER_METRIC" => Some(Self::Metric),
80 "TIER_TRACE" => Some(Self::Trace),
81 "TIER_AUDIT" => Some(Self::Audit),
82 _ => None,
83 }
84 }
85
86 fn values() -> &'static [Self] {
87 &[
88 Self::Unspecified,
89 Self::Log,
90 Self::Metric,
91 Self::Trace,
92 Self::Audit,
93 ]
94 }
95}
96
97impl FromStr for Tier {
98 type Err = UnknownVariant;
99
100 fn from_str(s: &str) -> Result<Self, Self::Err> {
101 match s.to_ascii_lowercase().as_str() {
102 "log" => Ok(Self::Log),
103 "metric" => Ok(Self::Metric),
104 "trace" => Ok(Self::Trace),
105 "audit" => Ok(Self::Audit),
106 _ => Err(UnknownVariant {
107 kind: "Tier",
108 value: s.to_string(),
109 }),
110 }
111 }
112}
113
114#[cfg(test)]
115mod tests {
116 use super::*;
117
118 #[test]
119 fn test_should_round_trip_via_i32() {
120 for v in Tier::values() {
121 assert_eq!(Tier::from_i32(v.to_i32()), Some(*v));
122 }
123 }
124
125 #[test]
126 fn test_should_parse_lowercase() {
127 assert_eq!("log".parse::<Tier>().unwrap(), Tier::Log);
128 assert_eq!("AUDIT".parse::<Tier>().unwrap(), Tier::Audit);
129 }
130
131 #[test]
132 fn test_should_reject_unknown() {
133 assert!("garbage".parse::<Tier>().is_err());
134 }
135
136 #[test]
137 fn test_should_round_trip_proto_name() {
138 for v in Tier::values() {
139 assert_eq!(Tier::from_proto_name(v.proto_name()), Some(*v));
140 }
141 }
142}