cassandra_protocol/frame/
message_supported.rs

1use super::Serialize;
2use crate::error;
3use crate::frame::{FromCursor, Version};
4use crate::types::{from_cursor_str, from_cursor_string_list, serialize_str, CIntShort, SHORT_LEN};
5use std::collections::HashMap;
6use std::io::{Cursor, Read};
7
8#[derive(Debug, PartialEq, Eq, Clone, Default)]
9pub struct BodyResSupported {
10    pub data: HashMap<String, Vec<String>>,
11}
12
13impl Serialize for BodyResSupported {
14    fn serialize(&self, cursor: &mut Cursor<&mut Vec<u8>>, version: Version) {
15        (self.data.len() as CIntShort).serialize(cursor, version);
16        self.data.iter().for_each(|(key, value)| {
17            serialize_str(cursor, key.as_str(), version);
18            (value.len() as CIntShort).serialize(cursor, version);
19            value
20                .iter()
21                .for_each(|s| serialize_str(cursor, s.as_str(), version));
22        })
23    }
24}
25
26impl FromCursor for BodyResSupported {
27    fn from_cursor(
28        cursor: &mut Cursor<&[u8]>,
29        _version: Version,
30    ) -> error::Result<BodyResSupported> {
31        let mut buff = [0; SHORT_LEN];
32        cursor.read_exact(&mut buff)?;
33
34        let l = i16::from_be_bytes(buff) as usize;
35        let mut data: HashMap<String, Vec<String>> = HashMap::with_capacity(l);
36        for _ in 0..l {
37            let name = from_cursor_str(cursor)?.to_string();
38            let val = from_cursor_string_list(cursor)?;
39            data.insert(name, val);
40        }
41
42        Ok(BodyResSupported { data })
43    }
44}
45
46#[cfg(test)]
47mod tests {
48    use super::*;
49    use crate::frame::traits::FromCursor;
50    use crate::frame::Version;
51    use std::io::Cursor;
52
53    #[test]
54    fn body_res_supported() {
55        let bytes = [
56            0, 1, // n options
57            // 1-st option
58            0, 2, 97, 98, // key [string] "ab"
59            0, 2, 0, 1, 97, 0, 1, 98, /* value ["a", "b"] */
60        ];
61        let mut data: HashMap<String, Vec<String>> = HashMap::new();
62        data.insert("ab".into(), vec!["a".into(), "b".into()]);
63        let expected = BodyResSupported { data };
64
65        {
66            let mut cursor: Cursor<&[u8]> = Cursor::new(&bytes);
67            let auth = BodyResSupported::from_cursor(&mut cursor, Version::V4).unwrap();
68            assert_eq!(auth, expected);
69        }
70
71        {
72            let mut buffer = Vec::new();
73            let mut cursor = Cursor::new(&mut buffer);
74            expected.serialize(&mut cursor, Version::V4);
75            assert_eq!(buffer, bytes);
76        }
77    }
78}