kf_protocol_api/
group_protocol_metadata.rs

1use std::io::Error;
2use std::io::ErrorKind;
3
4use serde::{Serialize, Deserialize};
5
6use kf_protocol::{Encoder, Decoder};
7use kf_protocol::bytes::{BufMut, Buf};
8use kf_protocol::Version;
9
10// -----------------------------------
11// ProtocolMetadata
12// -----------------------------------
13
14/*
15Reverse Engineered
16
17    ProtocolMetadata {
18        // 0x00, 0x00, 0x00, 0x10
19        // [         16          ] byte array length
20        len: i32,
21
22        // 0x00, 0x00, ??
23        reserved_i16: i16,
24
25        // 0x00, 0x00, 0x00, 0x01
26        // [         1           ] topics array length
27        // 0x00, 0x04, 0x74, 0x65, 0x73, 0x74
28        // [   len   ] [ t    e     s     t]
29        topics: Vec<String>,
30
31        pub reserved_i32: i32,
32    }
33
34*/
35
36#[derive(Debug, Serialize, Deserialize, Default, PartialEq)]
37pub struct ProtocolMetadata {
38    pub content: Option<Metadata>,
39}
40
41#[derive(Debug, Serialize, Deserialize, Default, PartialEq)]
42pub struct Metadata {
43    pub reserved_i16: i16,
44    pub topics: Vec<String>,
45    pub reserved_i32: i32,
46}
47
48impl Encoder for ProtocolMetadata {
49    fn write_size(&self, version: Version) -> usize {
50        let mut len = if let Some(content) = &self.content {
51            content.reserved_i16.write_size(version)
52                + content.topics.write_size(version)
53                + content.reserved_i32.write_size(version)
54        } else {
55            0
56        };
57        len += 4;
58        len
59    }
60
61    fn encode<T>(&self, dest: &mut T, version: Version) -> Result<(), Error>
62    where
63        T: BufMut,
64    {
65        if dest.remaining_mut() < 4 {
66            return Err(Error::new(
67                ErrorKind::UnexpectedEof,
68                "not enough capacity for length",
69            ));
70        }
71
72        let length = (self.write_size(version) as i32) - 4;
73        length.encode(dest, version)?;
74        if let Some(content) = &self.content {
75            content.reserved_i16.encode(dest, version)?;
76            content.topics.encode(dest, version)?;
77            content.reserved_i32.encode(dest, version)?;
78        }
79
80        Ok(())
81    }
82}
83
84impl Decoder for ProtocolMetadata {
85    fn decode<T>(&mut self, src: &mut T, version: Version) -> Result<(), Error>
86    where
87        T: Buf,
88    {
89        if src.remaining() < 4 {
90            return Err(Error::new(
91                ErrorKind::UnexpectedEof,
92                "not enough buf for i32",
93            ));
94        }
95
96        let mut len: i32 = 0;
97        len.decode(src, version)?;
98        if len > 0 {
99            if src.remaining() < len as usize {
100                return Err(Error::new(
101                    ErrorKind::UnexpectedEof,
102                    "not enough buf to decode metadata",
103                ));
104            }
105
106            let mut reserved_i16: i16 = 0;
107            let mut topics: Vec<String> = vec![];
108            let mut reserved_i32: i32 = 0;
109
110            reserved_i16.decode(src, version)?;
111            topics.decode(src, version)?;
112            reserved_i32.decode(src, version)?;
113
114            let metadata = Metadata {
115                reserved_i16,
116                topics,
117                reserved_i32,
118            };
119
120            *self = Self {
121                content: Some(metadata),
122            };
123        }
124        Ok(())
125    }
126}
127
128// -----------------------------------
129// Test Cases
130// -----------------------------------
131
132#[cfg(test)]
133mod test {
134    use std::io::Cursor;
135
136    use super::*;
137
138    #[test]
139    fn test_group_protocol_metadata_decoding() {
140        let data = [
141            0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x74, 0x65,
142            0x73, 0x74, 0x00, 0x00, 0x00, 0x00,
143        ];
144
145        let mut value = ProtocolMetadata::default();
146        let mut cursor = &mut Cursor::new(data);
147        let result = value.decode(&mut cursor, 4);
148        assert!(result.is_ok());
149
150        let metadata = Metadata {
151            reserved_i16: 0,
152            topics: vec!["test".to_owned()],
153            reserved_i32: 0,
154        };
155        let expected_value = ProtocolMetadata {
156            content: Some(metadata),
157        };
158
159        assert_eq!(value, expected_value);
160    }
161
162    #[test]
163    fn test2_metadata_group_decoding() {
164        let data = [
165            0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x05, 0x74, 0x65,
166            0x73, 0x74, 0x32, 0x00, 0x00, 0x00, 0x00,
167        ];
168
169        let mut value = ProtocolMetadata::default();
170        let mut cursor = &mut Cursor::new(data);
171        let result = value.decode(&mut cursor, 4);
172        assert!(result.is_ok());
173
174        let metadata = Metadata {
175            reserved_i16: 0,
176            topics: vec!["test2".to_owned()],
177            reserved_i32: 0,
178        };
179        let expected_value = ProtocolMetadata {
180            content: Some(metadata),
181        };
182
183        assert_eq!(value, expected_value);
184    }
185
186    #[test]
187    fn test_metadata_group_encoding() {
188        let mut data: Vec<u8> = vec![];
189        let exected_data = [
190            0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x74, 0x65,
191            0x73, 0x74, 0x00, 0x00, 0x00, 0x00,
192        ];
193
194        let metadata = Metadata {
195            reserved_i16: 0,
196            topics: vec!["test".to_owned()],
197            reserved_i32: 0,
198        };
199
200        let protocol = ProtocolMetadata {
201            content: Some(metadata),
202        };
203
204        let result = protocol.encode(&mut data, 4);
205        assert!(result.is_ok());
206
207        assert_eq!(data, exected_data);
208    }
209
210}