amqp_codec/types/
variant.rs1use std::hash::{Hash, Hasher};
2
3use bytes::Bytes;
4use bytestring::ByteString;
5use chrono::{DateTime, Utc};
6use fxhash::FxHashMap;
7use ordered_float::OrderedFloat;
8use uuid::Uuid;
9
10use crate::protocol::Annotations;
11use crate::types::{Descriptor, List, StaticSymbol, Str, Symbol};
12
13#[derive(Debug, Eq, PartialEq, Hash, Clone, Display, From)]
15pub enum Variant {
16 Null,
18
19 Boolean(bool),
21
22 Ubyte(u8),
24
25 Ushort(u16),
27
28 Uint(u32),
30
31 Ulong(u64),
33
34 Byte(i8),
36
37 Short(i16),
39
40 Int(i32),
42
43 Long(i64),
45
46 Float(OrderedFloat<f32>),
48
49 Double(OrderedFloat<f64>),
51
52 Char(char),
57
58 Timestamp(DateTime<Utc>),
63
64 Uuid(Uuid),
66
67 #[display(fmt = "Binary({:?})", _0)]
69 Binary(Bytes),
70
71 String(Str),
73
74 Symbol(Symbol),
76
77 StaticSymbol(StaticSymbol),
79
80 #[display(fmt = "List({:?})", _0)]
82 List(List),
83
84 Map(VariantMap),
86
87 #[display(fmt = "Described{:?}", _0)]
89 Described((Descriptor, Box<Variant>)),
90}
91
92impl From<ByteString> for Variant {
93 fn from(s: ByteString) -> Self {
94 Str::from(s).into()
95 }
96}
97
98impl From<String> for Variant {
99 fn from(s: String) -> Self {
100 Str::from(ByteString::from(s)).into()
101 }
102}
103
104impl From<&'static str> for Variant {
105 fn from(s: &'static str) -> Self {
106 Str::from(s).into()
107 }
108}
109
110impl PartialEq<str> for Variant {
111 fn eq(&self, other: &str) -> bool {
112 match self {
113 Variant::String(s) => s == other,
114 Variant::Symbol(s) => s == other,
115 _ => false,
116 }
117 }
118}
119
120impl Variant {
121 pub fn as_str(&self) -> Option<&str> {
122 match self {
123 Variant::String(s) => Some(s.as_str()),
124 Variant::Symbol(s) => Some(s.as_str()),
125 _ => None,
126 }
127 }
128
129 pub fn as_int(&self) -> Option<i32> {
130 match self {
131 Variant::Int(v) => Some(*v as i32),
132 _ => None,
133 }
134 }
135
136 pub fn as_long(&self) -> Option<i64> {
137 match self {
138 Variant::Ubyte(v) => Some(*v as i64),
139 Variant::Ushort(v) => Some(*v as i64),
140 Variant::Uint(v) => Some(*v as i64),
141 Variant::Ulong(v) => Some(*v as i64),
142 Variant::Byte(v) => Some(*v as i64),
143 Variant::Short(v) => Some(*v as i64),
144 Variant::Int(v) => Some(*v as i64),
145 Variant::Long(v) => Some(*v as i64),
146 _ => None,
147 }
148 }
149
150 pub fn to_bytes_str(&self) -> Option<ByteString> {
151 match self {
152 Variant::String(s) => Some(s.to_bytes_str()),
153 Variant::Symbol(s) => Some(s.to_bytes_str()),
154 _ => None,
155 }
156 }
157}
158
159#[derive(PartialEq, Eq, Clone, Debug, Display)]
160#[display(fmt = "{:?}", map)]
161pub struct VariantMap {
162 pub map: FxHashMap<Variant, Variant>,
163}
164
165impl VariantMap {
166 pub fn new(map: FxHashMap<Variant, Variant>) -> VariantMap {
167 VariantMap { map }
168 }
169}
170
171impl Hash for VariantMap {
172 fn hash<H: Hasher>(&self, _state: &mut H) {
173 unimplemented!()
174 }
175}
176
177#[derive(PartialEq, Clone, Debug, Display)]
178#[display(fmt = "{:?}", _0)]
179pub struct VecSymbolMap(pub Vec<(Symbol, Variant)>);
180
181impl Default for VecSymbolMap {
182 fn default() -> Self {
183 VecSymbolMap(Vec::with_capacity(8))
184 }
185}
186
187impl From<Annotations> for VecSymbolMap {
188 fn from(anns: Annotations) -> VecSymbolMap {
189 VecSymbolMap(anns.into_iter().collect())
190 }
191}
192
193impl std::ops::Deref for VecSymbolMap {
194 type Target = Vec<(Symbol, Variant)>;
195
196 fn deref(&self) -> &Self::Target {
197 &self.0
198 }
199}
200
201impl std::ops::DerefMut for VecSymbolMap {
202 fn deref_mut(&mut self) -> &mut Self::Target {
203 &mut self.0
204 }
205}
206
207#[derive(PartialEq, Clone, Debug, Display)]
208#[display(fmt = "{:?}", _0)]
209pub struct VecStringMap(pub Vec<(Str, Variant)>);
210
211impl Default for VecStringMap {
212 fn default() -> Self {
213 VecStringMap(Vec::with_capacity(8))
214 }
215}
216
217impl From<FxHashMap<Str, Variant>> for VecStringMap {
218 fn from(map: FxHashMap<Str, Variant>) -> VecStringMap {
219 VecStringMap(map.into_iter().collect())
220 }
221}
222
223impl std::ops::Deref for VecStringMap {
224 type Target = Vec<(Str, Variant)>;
225
226 fn deref(&self) -> &Self::Target {
227 &self.0
228 }
229}
230
231impl std::ops::DerefMut for VecStringMap {
232 fn deref_mut(&mut self) -> &mut Self::Target {
233 &mut self.0
234 }
235}
236
237#[cfg(test)]
238mod tests {
239 use super::*;
240
241 #[test]
242 fn bytes_eq() {
243 let bytes1 = Variant::Binary(Bytes::from(&b"hello"[..]));
244 let bytes2 = Variant::Binary(Bytes::from(&b"hello"[..]));
245 let bytes3 = Variant::Binary(Bytes::from(&b"world"[..]));
246
247 assert_eq!(bytes1, bytes2);
248 assert!(bytes1 != bytes3);
249 }
250
251 #[test]
252 fn string_eq() {
253 let a = Variant::String(ByteString::from("hello").into());
254 let b = Variant::String(ByteString::from("world!").into());
255
256 assert_eq!(Variant::String(ByteString::from("hello").into()), a);
257 assert!(a != b);
258 }
259
260 #[test]
261 fn symbol_eq() {
262 let a = Variant::Symbol(Symbol::from("hello"));
263 let b = Variant::Symbol(Symbol::from("world!"));
264
265 assert_eq!(Variant::Symbol(Symbol::from("hello")), a);
266 assert!(a != b);
267 }
268}