rocketmq_common/common/resource/
resource_pattern.rs1use serde::Deserialize;
16use serde::Deserializer;
17use serde::Serialize;
18use serde::Serializer;
19
20#[derive(Debug, Copy, Clone, Eq, PartialEq)]
21#[repr(u8)]
22pub enum ResourcePattern {
23 Any = 1,
24 Literal = 2,
25 Prefixed = 3,
26}
27
28impl ResourcePattern {
29 pub fn get_by_name(name: &str) -> Option<Self> {
31 if name.eq_ignore_ascii_case("ANY") {
32 Some(Self::Any)
33 } else if name.eq_ignore_ascii_case("LITERAL") {
34 Some(Self::Literal)
35 } else if name.eq_ignore_ascii_case("PREFIXED") {
36 Some(Self::Prefixed)
37 } else {
38 None
39 }
40 }
41
42 #[inline]
43 pub fn code(self) -> u8 {
44 self as u8
45 }
46
47 #[inline]
48 pub fn name(self) -> &'static str {
49 match self {
50 Self::Any => "ANY",
51 Self::Literal => "LITERAL",
52 Self::Prefixed => "PREFIXED",
53 }
54 }
55}
56
57impl Serialize for ResourcePattern {
58 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
59 where
60 S: Serializer,
61 {
62 serializer.serialize_u8(self.code())
63 }
64}
65
66impl<'de> Deserialize<'de> for ResourcePattern {
67 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
68 where
69 D: Deserializer<'de>,
70 {
71 let v = u8::deserialize(deserializer)?;
72 match v {
73 1 => Ok(ResourcePattern::Any),
74 2 => Ok(ResourcePattern::Literal),
75 3 => Ok(ResourcePattern::Prefixed),
76 _ => Err(serde::de::Error::custom("invalid ResourcePattern code")),
77 }
78 }
79}
80
81#[cfg(test)]
82mod tests {
83 use crate::common::resource::resource_pattern::ResourcePattern;
84
85 #[test]
86 fn given_string_any_return_enum_value() {
87 let any = ResourcePattern::get_by_name("ANY");
88 assert_eq!(Some(ResourcePattern::Any), any);
89 }
90
91 #[test]
92 fn given_string_literal_return_enum_value() {
93 let literal = ResourcePattern::get_by_name("LITERAL");
94 assert_eq!(Some(ResourcePattern::Literal), literal);
95 }
96
97 #[test]
98 fn given_string_prefixed_return_enum_value() {
99 let prefixed = ResourcePattern::get_by_name("PREFIXED");
100 assert_eq!(Some(ResourcePattern::Prefixed), prefixed);
101 }
102
103 #[test]
104 fn get_by_name_is_case_insensitive() {
105 assert_eq!(Some(ResourcePattern::Any), ResourcePattern::get_by_name("aNy"));
106 assert_eq!(Some(ResourcePattern::Literal), ResourcePattern::get_by_name("LiTeRaL"));
107 assert_eq!(
108 Some(ResourcePattern::Prefixed),
109 ResourcePattern::get_by_name("pReFixed")
110 );
111 }
112
113 #[test]
114 fn invalid_name_returns_none() {
115 assert!(ResourcePattern::get_by_name("UNKNOWN").is_none());
116 assert!(ResourcePattern::get_by_name("123").is_none());
117 assert!(ResourcePattern::get_by_name("").is_none());
118 }
119
120 #[test]
121 fn name_and_code_methods_are_consistent() {
122 assert_eq!("ANY", ResourcePattern::Any.name());
123 assert_eq!(1, ResourcePattern::Any.code());
124 assert_eq!("LITERAL", ResourcePattern::Literal.name());
125 assert_eq!(2, ResourcePattern::Literal.code());
126 assert_eq!("PREFIXED", ResourcePattern::Prefixed.name());
127 assert_eq!(3, ResourcePattern::Prefixed.code());
128 }
129
130 #[test]
131 fn serde_json_serializes_to_number() {
132 assert_eq!(
133 "1",
134 serde_json::to_string(&ResourcePattern::Any).expect("ResourcePattern::Any must serialize")
135 );
136 assert_eq!(
137 "2",
138 serde_json::to_string(&ResourcePattern::Literal).expect("ResourcePattern::Literal must serialize")
139 );
140 assert_eq!(
141 "3",
142 serde_json::to_string(&ResourcePattern::Prefixed).expect("ResourcePattern::Prefixed must serialize")
143 );
144 }
145
146 #[test]
147 fn serde_json_deserializes_from_number() {
148 let any: ResourcePattern = serde_json::from_str("1").expect("Must deserialize 1");
149 assert_eq!(ResourcePattern::Any, any);
150
151 let literal: ResourcePattern = serde_json::from_str("2").expect("Must deserialize 2");
152 assert_eq!(ResourcePattern::Literal, literal);
153
154 let prefixed: ResourcePattern = serde_json::from_str("3").expect("Must deserialize 3");
155 assert_eq!(ResourcePattern::Prefixed, prefixed);
156 }
157
158 #[test]
159 fn serde_json_deserializes_invalid_fails() {
160 assert!(serde_json::from_str::<ResourcePattern>("0").is_err());
161 assert!(serde_json::from_str::<ResourcePattern>("999").is_err());
162 }
163
164 #[test]
165 fn serde_json_roundtrip_variants() {
166 for &variant in &[
167 ResourcePattern::Any,
168 ResourcePattern::Literal,
169 ResourcePattern::Prefixed,
170 ] {
171 let serialized = serde_json::to_string(&variant)
172 .unwrap_or_else(|e| panic!("Could not serialize ResourcePattern::{:?}: {}", &variant.name(), e));
173 let parsed: ResourcePattern = serde_json::from_str(&serialized)
174 .unwrap_or_else(|e| panic!("Could not parse {:?} as ResourcePattern: {}", &serialized, e));
175 assert_eq!(variant, parsed);
176 }
177 }
178}