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