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#[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#[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}