amq_protocol_types/
flags.rs1use crate::types::Boolean;
2
3use serde::{Deserialize, Serialize};
4
5#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
7pub struct AMQPFlags {
8 flags: Vec<(String, Boolean)>,
9}
10
11impl AMQPFlags {
12 pub fn add_flag(&mut self, name: String, flag: Boolean) {
14 self.flags.push((name, flag));
15 }
16
17 pub fn get_flag(&self, name: &str) -> Option<Boolean> {
19 self.flags.iter().find(|(n, _)| n == name).map(|(_, v)| *v)
20 }
21
22 pub fn get_bytes(&self) -> Vec<u8> {
24 self.flags
25 .chunks(8)
26 .map(|v| {
27 v.iter()
28 .enumerate()
29 .map(|(idx, (_, b))| if *b { 1 << idx } else { 0 })
30 .sum()
31 })
32 .collect()
33 }
34
35 pub fn from_bytes<I: nom::Input<Item = u8>>(names: &[&str], bytes: I) -> AMQPFlags {
37 let flags = names
38 .iter()
39 .map(ToString::to_string)
40 .zip(
41 bytes
42 .iter_elements()
43 .flat_map(|b| (0..8u8).map(move |s| ((b >> s) & 1) == 1)),
44 )
45 .collect();
46
47 AMQPFlags { flags }
48 }
49}
50
51#[cfg(test)]
52mod test {
53 use super::*;
54
55 #[test]
56 fn test_empty_flags() {
57 let empty: &[u8] = &[];
58 assert_eq!(AMQPFlags::default().get_bytes().as_slice(), empty);
59 }
60
61 #[test]
62 fn test_flags() {
63 let mut flags = AMQPFlags::default();
64 flags.add_flag("a".to_string(), true);
65 flags.add_flag("b".to_string(), false);
66 flags.add_flag("c".to_string(), false);
67 flags.add_flag("d".to_string(), true);
68 flags.add_flag("e".to_string(), true);
69 assert_eq!(flags.get_bytes().as_slice(), &[0b00011001])
70 }
71
72 #[test]
73 fn test_many_flags() {
74 let mut flags = AMQPFlags::default();
75 flags.add_flag("a".to_string(), true);
76 flags.add_flag("b".to_string(), false);
77 flags.add_flag("c".to_string(), false);
78 flags.add_flag("d".to_string(), true);
79 flags.add_flag("e".to_string(), true);
80 flags.add_flag("f".to_string(), true);
81 flags.add_flag("g".to_string(), false);
82 flags.add_flag("h".to_string(), false);
83 flags.add_flag("i".to_string(), true);
84 flags.add_flag("j".to_string(), true);
85 assert_eq!(flags.get_bytes().as_slice(), &[0b00111001, 0b00000011])
86 }
87
88 #[test]
89 fn test_lookup_flags() {
90 let mut flags = AMQPFlags::default();
91 flags.add_flag("a".to_string(), true);
92 flags.add_flag("b".to_string(), false);
93 flags.add_flag("c".to_string(), false);
94 flags.add_flag("d".to_string(), true);
95 flags.add_flag("e".to_string(), true);
96 flags.add_flag("f".to_string(), true);
97 flags.add_flag("g".to_string(), false);
98 flags.add_flag("h".to_string(), false);
99 flags.add_flag("i".to_string(), true);
100 flags.add_flag("j".to_string(), true);
101 assert_eq!(flags.get_flag("a"), Some(true));
102 assert_eq!(flags.get_flag("d"), Some(true));
103 assert_eq!(flags.get_flag("e"), Some(true));
104 assert_eq!(flags.get_flag("b"), Some(false));
105 assert_eq!(flags.get_flag("j"), Some(true));
106 assert_eq!(flags.get_flag("h"), Some(false));
107 assert_eq!(flags.get_flag("z"), None);
108 }
109}