amq_protocol_types/
value.rs

1use crate::types::*;
2
3use serde::{Deserialize, Serialize};
4use serde_json::Value;
5
6/// Enumeration referencing the possible AMQP values depending on the types
7#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
8pub enum AMQPValue {
9    /// A bool
10    Boolean(Boolean),
11    /// An i8
12    ShortShortInt(ShortShortInt),
13    /// A u8
14    ShortShortUInt(ShortShortUInt),
15    /// An i16
16    ShortInt(ShortInt),
17    /// A u16
18    ShortUInt(ShortUInt),
19    /// An i32
20    LongInt(LongInt),
21    /// A u32
22    LongUInt(LongUInt),
23    /// An i64
24    LongLongInt(LongLongInt),
25    /// An f32
26    Float(Float),
27    /// An f64
28    Double(Double),
29    /// A decimal value
30    DecimalValue(DecimalValue),
31    /// A String (deprecated)
32    ShortString(ShortString),
33    /// A String
34    LongString(LongString),
35    /// An array of AMQPValue
36    FieldArray(FieldArray),
37    /// A timestamp (u64)
38    Timestamp(Timestamp),
39    /// A Map<String, AMQPValue>
40    FieldTable(FieldTable),
41    /// An array of bytes (RabbitMQ specific)
42    ByteArray(ByteArray),
43    /// No value
44    Void,
45}
46
47impl AMQPValue {
48    /// Get the AMQPType of an AMQPValue
49    pub fn get_type(&self) -> AMQPType {
50        match *self {
51            AMQPValue::Boolean(_) => AMQPType::Boolean,
52            AMQPValue::ShortShortInt(_) => AMQPType::ShortShortInt,
53            AMQPValue::ShortShortUInt(_) => AMQPType::ShortShortUInt,
54            AMQPValue::ShortInt(_) => AMQPType::ShortInt,
55            AMQPValue::ShortUInt(_) => AMQPType::ShortUInt,
56            AMQPValue::LongInt(_) => AMQPType::LongInt,
57            AMQPValue::LongUInt(_) => AMQPType::LongUInt,
58            AMQPValue::LongLongInt(_) => AMQPType::LongLongInt,
59            AMQPValue::Float(_) => AMQPType::Float,
60            AMQPValue::Double(_) => AMQPType::Double,
61            AMQPValue::DecimalValue(_) => AMQPType::DecimalValue,
62            AMQPValue::ShortString(_) => AMQPType::ShortString,
63            AMQPValue::LongString(_) => AMQPType::LongString,
64            AMQPValue::FieldArray(_) => AMQPType::FieldArray,
65            AMQPValue::Timestamp(_) => AMQPType::Timestamp,
66            AMQPValue::FieldTable(_) => AMQPType::FieldTable,
67            AMQPValue::ByteArray(_) => AMQPType::ByteArray,
68            AMQPValue::Void => AMQPType::Void,
69        }
70    }
71
72    /// Convert a serde_json::Value into an AMQPValue
73    pub fn try_from(value: &Value, amqp_type: AMQPType) -> Option<AMQPValue> {
74        match amqp_type {
75            AMQPType::Boolean => value.as_bool().map(AMQPValue::Boolean),
76            AMQPType::ShortShortInt => value
77                .as_i64()
78                .map(|i| AMQPValue::ShortShortInt(i as ShortShortInt)),
79            AMQPType::ShortShortUInt => value
80                .as_u64()
81                .map(|u| AMQPValue::ShortShortUInt(u as ShortShortUInt)),
82            AMQPType::ShortInt => value.as_i64().map(|i| AMQPValue::ShortInt(i as ShortInt)),
83            AMQPType::ShortUInt => value.as_u64().map(|u| AMQPValue::ShortUInt(u as ShortUInt)),
84            AMQPType::LongInt => value.as_i64().map(|i| AMQPValue::LongInt(i as LongInt)),
85            AMQPType::LongUInt => value.as_u64().map(|u| AMQPValue::LongUInt(u as LongUInt)),
86            AMQPType::LongLongInt => value
87                .as_i64()
88                .map(|i| AMQPValue::LongLongInt(i as LongLongInt)),
89            AMQPType::LongLongUInt => value
90                .as_i64()
91                .map(|i| AMQPValue::LongLongInt(i as LongLongInt)), /* Not a typo; AMQPValue::LongLongUInt doesn't exist */
92            AMQPType::Float => value.as_f64().map(|i| AMQPValue::Float(i as Float)),
93            AMQPType::Double => value.as_f64().map(|i| AMQPValue::Double(i as Double)),
94            AMQPType::DecimalValue => None,
95            AMQPType::ShortString => value
96                .as_str()
97                .map(ShortString::from)
98                .map(AMQPValue::ShortString),
99            AMQPType::LongString => value
100                .as_str()
101                .map(LongString::from)
102                .map(AMQPValue::LongString),
103            AMQPType::FieldArray => None,
104            AMQPType::Timestamp => value.as_u64().map(|t| AMQPValue::Timestamp(t as Timestamp)),
105            AMQPType::FieldTable => None,
106            AMQPType::ByteArray => None,
107            AMQPType::Void => value.as_null().map(|_| AMQPValue::Void),
108        }
109    }
110
111    /// If the value is bool, returns associated value. Returns None otherwise.
112    pub fn as_bool(&self) -> Option<Boolean> {
113        match self {
114            AMQPValue::Boolean(value) => Some(*value),
115            _ => None,
116        }
117    }
118
119    /// If the value is ShortShortInt, returns associated value. Returns None otherwise.
120    pub fn as_short_short_int(&self) -> Option<ShortShortInt> {
121        match self {
122            AMQPValue::ShortShortInt(value) => Some(*value),
123            _ => None,
124        }
125    }
126
127    /// If the value is ShortShortUInt, returns associated value. Returns None otherwise.
128    pub fn as_short_short_uint(&self) -> Option<ShortShortUInt> {
129        match self {
130            AMQPValue::ShortShortUInt(value) => Some(*value),
131            _ => None,
132        }
133    }
134
135    /// If the value is ShortInt, returns associated value. Returns None otherwise.
136    pub fn as_short_int(&self) -> Option<ShortInt> {
137        match self {
138            AMQPValue::ShortInt(value) => Some(*value),
139            _ => None,
140        }
141    }
142
143    /// If the value is ShortUInt, returns associated value. Returns None otherwise.
144    pub fn as_short_uint(&self) -> Option<ShortUInt> {
145        match self {
146            AMQPValue::ShortUInt(value) => Some(*value),
147            _ => None,
148        }
149    }
150
151    /// If the value is LongInt, returns associated value. Returns None otherwise.
152    pub fn as_long_int(&self) -> Option<LongInt> {
153        match self {
154            AMQPValue::LongInt(value) => Some(*value),
155            _ => None,
156        }
157    }
158
159    /// If the value is LongUInt, returns associated value. Returns None otherwise.
160    pub fn as_long_uint(&self) -> Option<LongUInt> {
161        match self {
162            AMQPValue::LongUInt(value) => Some(*value),
163            _ => None,
164        }
165    }
166
167    /// If the value is LongLongInt, returns associated value. Returns None otherwise.
168    pub fn as_long_long_int(&self) -> Option<LongLongInt> {
169        match self {
170            AMQPValue::LongLongInt(value) => Some(*value),
171            _ => None,
172        }
173    }
174
175    /// If the value is Float, returns associated value. Returns None otherwise.
176    pub fn as_float(&self) -> Option<Float> {
177        match self {
178            AMQPValue::Float(value) => Some(*value),
179            _ => None,
180        }
181    }
182
183    /// If the value is Double, returns associated value. Returns None otherwise.
184    pub fn as_double(&self) -> Option<Double> {
185        match self {
186            AMQPValue::Double(value) => Some(*value),
187            _ => None,
188        }
189    }
190
191    /// If the value is DecimalValue, returns associated value. Returns None otherwise.
192    pub fn as_decimal_value(&self) -> Option<DecimalValue> {
193        match self {
194            AMQPValue::DecimalValue(value) => Some(*value),
195            _ => None,
196        }
197    }
198
199    /// If the value is ShortString, returns associated value as str. Returns None otherwise.
200    pub fn as_short_string(&self) -> Option<&ShortString> {
201        match self {
202            AMQPValue::ShortString(value) => Some(value),
203            _ => None,
204        }
205    }
206
207    /// If the value is LongString, returns associated value as bytes. Returns None otherwise.
208    pub fn as_long_string(&self) -> Option<&LongString> {
209        match self {
210            AMQPValue::LongString(value) => Some(value),
211            _ => None,
212        }
213    }
214
215    /// If the value is FieldArray, returns associated value. Returns None otherwise.
216    pub fn as_array(&self) -> Option<&FieldArray> {
217        match self {
218            AMQPValue::FieldArray(value) => Some(value),
219            _ => None,
220        }
221    }
222
223    /// If the value is Timestamp, returns associated value. Returns None otherwise.
224    pub fn as_timestamp(&self) -> Option<Timestamp> {
225        match self {
226            AMQPValue::Timestamp(value) => Some(*value),
227            _ => None,
228        }
229    }
230
231    /// If the value is FieldTable, returns associated value. Returns None otherwise.
232    pub fn as_field_table(&self) -> Option<&FieldTable> {
233        match self {
234            AMQPValue::FieldTable(value) => Some(value),
235            _ => None,
236        }
237    }
238
239    /// If the value is ByteArray, returns associated value. Returns None otherwise.
240    pub fn as_byte_array(&self) -> Option<&ByteArray> {
241        match self {
242            AMQPValue::ByteArray(value) => Some(value),
243            _ => None,
244        }
245    }
246
247    /// Returns true if value is Void.
248    pub fn as_void(&self) -> Option<()> {
249        match self {
250            AMQPValue::Void => Some(()),
251            _ => None,
252        }
253    }
254}
255
256impl From<Boolean> for AMQPValue {
257    fn from(v: Boolean) -> Self {
258        AMQPValue::Boolean(v)
259    }
260}
261
262impl From<ShortShortInt> for AMQPValue {
263    fn from(v: ShortShortInt) -> Self {
264        AMQPValue::ShortShortInt(v)
265    }
266}
267
268impl From<ShortShortUInt> for AMQPValue {
269    fn from(v: ShortShortUInt) -> Self {
270        AMQPValue::ShortShortUInt(v)
271    }
272}
273
274impl From<ShortInt> for AMQPValue {
275    fn from(v: ShortInt) -> Self {
276        AMQPValue::ShortInt(v)
277    }
278}
279
280impl From<ShortUInt> for AMQPValue {
281    fn from(v: ShortUInt) -> Self {
282        AMQPValue::ShortUInt(v)
283    }
284}
285
286impl From<LongInt> for AMQPValue {
287    fn from(v: LongInt) -> Self {
288        AMQPValue::LongInt(v)
289    }
290}
291
292impl From<LongUInt> for AMQPValue {
293    fn from(v: LongUInt) -> Self {
294        AMQPValue::LongUInt(v)
295    }
296}
297
298impl From<LongLongInt> for AMQPValue {
299    fn from(v: LongLongInt) -> Self {
300        AMQPValue::LongLongInt(v)
301    }
302}
303
304impl From<Float> for AMQPValue {
305    fn from(v: Float) -> Self {
306        AMQPValue::Float(v)
307    }
308}
309
310impl From<Double> for AMQPValue {
311    fn from(v: Double) -> Self {
312        AMQPValue::Double(v)
313    }
314}
315
316impl From<DecimalValue> for AMQPValue {
317    fn from(v: DecimalValue) -> Self {
318        AMQPValue::DecimalValue(v)
319    }
320}
321
322impl From<ShortString> for AMQPValue {
323    fn from(v: ShortString) -> Self {
324        AMQPValue::ShortString(v)
325    }
326}
327
328impl From<LongString> for AMQPValue {
329    fn from(v: LongString) -> Self {
330        AMQPValue::LongString(v)
331    }
332}
333
334impl From<FieldArray> for AMQPValue {
335    fn from(v: FieldArray) -> Self {
336        AMQPValue::FieldArray(v)
337    }
338}
339
340impl From<Timestamp> for AMQPValue {
341    fn from(v: Timestamp) -> Self {
342        AMQPValue::Timestamp(v)
343    }
344}
345
346impl From<FieldTable> for AMQPValue {
347    fn from(v: FieldTable) -> Self {
348        AMQPValue::FieldTable(v)
349    }
350}
351
352impl From<ByteArray> for AMQPValue {
353    fn from(v: ByteArray) -> Self {
354        AMQPValue::ByteArray(v)
355    }
356}
357
358#[cfg(test)]
359mod test {
360    use super::*;
361
362    use serde_json::Number;
363
364    #[test]
365    fn test_from_bool_value() {
366        assert_eq!(
367            AMQPValue::try_from(&Value::Bool(false), AMQPType::Boolean),
368            Some(AMQPValue::Boolean(false))
369        );
370        assert_eq!(
371            AMQPValue::try_from(&Value::Bool(true), AMQPType::Boolean),
372            Some(AMQPValue::Boolean(true))
373        );
374    }
375
376    #[test]
377    fn test_from_number_value() {
378        assert_eq!(
379            AMQPValue::try_from(&Value::Number(Number::from(42)), AMQPType::LongLongUInt),
380            Some(AMQPValue::LongLongInt(42))
381        );
382        assert_eq!(
383            AMQPValue::try_from(&Value::Number(Number::from(-42)), AMQPType::LongLongInt),
384            Some(AMQPValue::LongLongInt(-42))
385        );
386        assert_eq!(
387            AMQPValue::try_from(
388                &Value::Number(Number::from_f64(42.42).unwrap()),
389                AMQPType::Double
390            ),
391            Some(AMQPValue::Double(42.42))
392        );
393    }
394
395    #[test]
396    fn test_from_string_value() {
397        assert_eq!(
398            AMQPValue::try_from(&Value::String(String::new()), AMQPType::LongString),
399            Some(AMQPValue::LongString(LongString::default()))
400        );
401        assert_eq!(
402            AMQPValue::try_from(&Value::String("test".to_string()), AMQPType::LongString),
403            Some(AMQPValue::LongString("test".into()))
404        );
405    }
406
407    #[test]
408    fn test_from_null_value() {
409        assert_eq!(
410            AMQPValue::try_from(&Value::Null, AMQPType::Void),
411            Some(AMQPValue::Void)
412        );
413    }
414}