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(bytes.iter_elements().flat_map(|b| {
41 let mut v = Vec::new();
42 for s in 0..8 {
43 v.push(((b & (1 << s)) >> s) == 1)
44 }
45 v
46 }))
47 .collect();
48
49 AMQPFlags { flags }
50 }
51}
52
53#[cfg(test)]
54mod test {
55 use super::*;
56
57 #[test]
58 fn test_empty_flags() {
59 let empty: &[u8] = &[];
60 assert_eq!(AMQPFlags::default().get_bytes().as_slice(), empty);
61 }
62
63 #[test]
64 fn test_flags() {
65 let mut flags = AMQPFlags::default();
66 flags.add_flag("a".to_string(), true);
67 flags.add_flag("b".to_string(), false);
68 flags.add_flag("c".to_string(), false);
69 flags.add_flag("d".to_string(), true);
70 flags.add_flag("e".to_string(), true);
71 assert_eq!(flags.get_bytes().as_slice(), &[0b00011001])
72 }
73
74 #[test]
75 fn test_many_flags() {
76 let mut flags = AMQPFlags::default();
77 flags.add_flag("a".to_string(), true);
78 flags.add_flag("b".to_string(), false);
79 flags.add_flag("c".to_string(), false);
80 flags.add_flag("d".to_string(), true);
81 flags.add_flag("e".to_string(), true);
82 flags.add_flag("f".to_string(), true);
83 flags.add_flag("g".to_string(), false);
84 flags.add_flag("h".to_string(), false);
85 flags.add_flag("i".to_string(), true);
86 flags.add_flag("j".to_string(), true);
87 assert_eq!(flags.get_bytes().as_slice(), &[0b00111001, 0b00000011])
88 }
89
90 #[test]
91 fn test_lookup_flags() {
92 let mut flags = AMQPFlags::default();
93 flags.add_flag("a".to_string(), true);
94 flags.add_flag("b".to_string(), false);
95 flags.add_flag("c".to_string(), false);
96 flags.add_flag("d".to_string(), true);
97 flags.add_flag("e".to_string(), true);
98 flags.add_flag("f".to_string(), true);
99 flags.add_flag("g".to_string(), false);
100 flags.add_flag("h".to_string(), false);
101 flags.add_flag("i".to_string(), true);
102 flags.add_flag("j".to_string(), true);
103 assert_eq!(flags.get_flag("a"), Some(true));
104 assert_eq!(flags.get_flag("d"), Some(true));
105 assert_eq!(flags.get_flag("e"), Some(true));
106 assert_eq!(flags.get_flag("b"), Some(false));
107 assert_eq!(flags.get_flag("j"), Some(true));
108 assert_eq!(flags.get_flag("h"), Some(false));
109 assert_eq!(flags.get_flag("z"), None);
110 }
111}