1use bytes::{Buf, BufMut};
4
5use crate::{
6 Decode, Encode, ProtocolError, UnknownTaggedFields,
7 primitives::{
8 array::{array_len_prefix_len, get_array_len, put_array_len},
9 fixed::{get_bool, get_i32, get_i64, put_bool, put_i32, put_i64},
10 string_bytes::{
11 compact_nullable_string_len, compact_string_len, get_compact_nullable_string_owned,
12 get_compact_string_owned, get_nullable_string_owned, get_string_owned,
13 nullable_string_len, put_compact_nullable_string, put_compact_string,
14 put_nullable_string, put_string, string_len,
15 },
16 uuid::{Uuid, get_uuid, put_uuid},
17 },
18 tagged_fields::{WriteTaggedFields, read_tagged_fields, tagged_fields_len},
19};
20pub const API_KEY: i16 = 52;
21pub const MIN_VERSION: i16 = 0;
22pub const MAX_VERSION: i16 = 2;
23pub const LATEST_STABLE_VERSION: i16 = 2;
24pub const FLEXIBLE_MIN: i16 = 0;
25#[inline]
26#[must_use]
27pub fn is_flexible(version: i16) -> bool {
28 version >= FLEXIBLE_MIN
29}
30#[derive(Debug, Clone, PartialEq, Eq)]
31pub struct VoteRequest {
32 pub cluster_id: Option<String>,
33 pub voter_id: i32,
34 pub topics: Vec<TopicData>,
35 pub unknown_tagged_fields: UnknownTaggedFields,
36}
37impl Default for VoteRequest {
38 fn default() -> Self {
39 Self {
40 cluster_id: None,
41 voter_id: -1i32,
42 topics: Vec::new(),
43 unknown_tagged_fields: UnknownTaggedFields::default(),
44 }
45 }
46}
47impl Encode for VoteRequest {
48 fn encode<B: BufMut>(&self, buf: &mut B, version: i16) -> Result<(), ProtocolError> {
49 if !(MIN_VERSION..=MAX_VERSION).contains(&version) {
50 return Err(ProtocolError::UnsupportedVersion {
51 api_key: API_KEY,
52 version,
53 });
54 }
55 let flex = is_flexible(version);
56 if version >= 0 {
57 if flex {
58 put_compact_nullable_string(buf, self.cluster_id.as_deref())?;
59 } else {
60 put_nullable_string(buf, self.cluster_id.as_deref())?;
61 }
62 }
63 if version >= 1 {
64 put_i32(buf, self.voter_id);
65 }
66 if version >= 0 {
67 {
68 put_array_len(buf, (self.topics).len(), flex)?;
69 for it in &self.topics {
70 it.encode(buf, version)?;
71 }
72 }
73 }
74 if flex {
75 let tagged = WriteTaggedFields::new();
76 tagged.write(buf, &self.unknown_tagged_fields)?;
77 }
78 Ok(())
79 }
80 fn encoded_len(&self, version: i16) -> usize {
81 let flex = is_flexible(version);
82 let mut n: usize = 0;
83 if version >= 0 {
84 n += if flex {
85 compact_nullable_string_len(self.cluster_id.as_deref())
86 } else {
87 nullable_string_len(self.cluster_id.as_deref())
88 };
89 }
90 if version >= 1 {
91 n += 4;
92 }
93 if version >= 0 {
94 n += {
95 let prefix = array_len_prefix_len((self.topics).len(), flex);
96 let body: usize = (self.topics).iter().map(|it| it.encoded_len(version)).sum();
97 prefix + body
98 };
99 }
100 if flex {
101 let known_pairs: Vec<(u32, usize)> = Vec::new();
102 n += tagged_fields_len(&known_pairs, &self.unknown_tagged_fields);
103 }
104 n
105 }
106}
107impl Decode<'_> for VoteRequest {
108 fn decode<B: Buf>(buf: &mut B, version: i16) -> Result<Self, ProtocolError> {
109 if !(MIN_VERSION..=MAX_VERSION).contains(&version) {
110 return Err(ProtocolError::UnsupportedVersion {
111 api_key: API_KEY,
112 version,
113 });
114 }
115 let flex = is_flexible(version);
116 let mut out = Self::default();
117 if version >= 0 {
118 out.cluster_id = if flex {
119 get_compact_nullable_string_owned(buf)?
120 } else {
121 get_nullable_string_owned(buf)?
122 };
123 }
124 if version >= 1 {
125 out.voter_id = get_i32(buf)?;
126 }
127 if version >= 0 {
128 out.topics = {
129 let n = get_array_len(buf, flex)?;
130 let mut v = Vec::with_capacity(n);
131 for _ in 0..n {
132 v.push(TopicData::decode(buf, version)?);
133 }
134 v
135 };
136 }
137 if flex {
138 out.unknown_tagged_fields = read_tagged_fields(buf, |_tag, _payload| Ok(false))?;
139 }
140 Ok(out)
141 }
142}
143#[cfg(test)]
144impl VoteRequest {
145 #[must_use]
146 pub fn populated(version: i16) -> Self {
147 let mut m = Self::default();
148 if version >= 0 {
149 m.cluster_id = Some("x".to_owned());
150 }
151 if version >= 1 {
152 m.voter_id = 1i32;
153 }
154 if version >= 0 {
155 m.topics = vec![TopicData::populated(version)];
156 }
157 m
158 }
159}
160#[derive(Debug, Clone, PartialEq, Eq, Default)]
161pub struct TopicData {
162 pub topic_name: String,
163 pub partitions: Vec<PartitionData>,
164 pub unknown_tagged_fields: UnknownTaggedFields,
165}
166impl Encode for TopicData {
167 fn encode<B: BufMut>(&self, buf: &mut B, version: i16) -> Result<(), ProtocolError> {
168 let flex = version >= 0;
169 if version >= 0 {
170 if flex {
171 put_compact_string(buf, &self.topic_name)?;
172 } else {
173 put_string(buf, &self.topic_name)?;
174 }
175 }
176 if version >= 0 {
177 {
178 put_array_len(buf, (self.partitions).len(), flex)?;
179 for it in &self.partitions {
180 it.encode(buf, version)?;
181 }
182 }
183 }
184 if flex {
185 let tagged = WriteTaggedFields::new();
186 tagged.write(buf, &self.unknown_tagged_fields)?;
187 }
188 Ok(())
189 }
190 fn encoded_len(&self, version: i16) -> usize {
191 let flex = version >= 0;
192 let mut n: usize = 0;
193 if version >= 0 {
194 n += if flex {
195 compact_string_len(&self.topic_name)
196 } else {
197 string_len(&self.topic_name)
198 };
199 }
200 if version >= 0 {
201 n += {
202 let prefix = array_len_prefix_len((self.partitions).len(), flex);
203 let body: usize = (self.partitions)
204 .iter()
205 .map(|it| it.encoded_len(version))
206 .sum();
207 prefix + body
208 };
209 }
210 if flex {
211 let known_pairs: Vec<(u32, usize)> = Vec::new();
212 n += tagged_fields_len(&known_pairs, &self.unknown_tagged_fields);
213 }
214 n
215 }
216}
217impl Decode<'_> for TopicData {
218 fn decode<B: Buf>(buf: &mut B, version: i16) -> Result<Self, ProtocolError> {
219 let flex = version >= 0;
220 let mut out = Self::default();
221 if version >= 0 {
222 out.topic_name = if flex {
223 get_compact_string_owned(buf)?
224 } else {
225 get_string_owned(buf)?
226 };
227 }
228 if version >= 0 {
229 out.partitions = {
230 let n = get_array_len(buf, flex)?;
231 let mut v = Vec::with_capacity(n);
232 for _ in 0..n {
233 v.push(PartitionData::decode(buf, version)?);
234 }
235 v
236 };
237 }
238 if flex {
239 out.unknown_tagged_fields = read_tagged_fields(buf, |_tag, _payload| Ok(false))?;
240 }
241 Ok(out)
242 }
243}
244#[cfg(test)]
245impl TopicData {
246 #[must_use]
247 pub fn populated(version: i16) -> Self {
248 let mut m = Self::default();
249 if version >= 0 {
250 m.topic_name = "x".to_owned();
251 }
252 if version >= 0 {
253 m.partitions = vec![PartitionData::populated(version)];
254 }
255 m
256 }
257}
258#[derive(Debug, Clone, PartialEq, Eq, Default)]
259pub struct PartitionData {
260 pub partition_index: i32,
261 pub replica_epoch: i32,
262 pub replica_id: i32,
263 pub replica_directory_id: Uuid,
264 pub voter_directory_id: Uuid,
265 pub last_offset_epoch: i32,
266 pub last_offset: i64,
267 pub pre_vote: bool,
268 pub unknown_tagged_fields: UnknownTaggedFields,
269}
270impl PartitionData {
271 fn encode_field_0<B: BufMut>(&self, buf: &mut B, version: i16, _flex: bool) {
272 if version >= 0 {
273 put_i32(buf, self.partition_index);
274 }
275 }
276 fn encode_field_1<B: BufMut>(&self, buf: &mut B, version: i16, _flex: bool) {
277 if version >= 0 {
278 put_i32(buf, self.replica_epoch);
279 }
280 }
281 fn encode_field_2<B: BufMut>(&self, buf: &mut B, version: i16, _flex: bool) {
282 if version >= 0 {
283 put_i32(buf, self.replica_id);
284 }
285 }
286 fn encode_field_3<B: BufMut>(&self, buf: &mut B, version: i16, _flex: bool) {
287 if version >= 1 {
288 put_uuid(buf, self.replica_directory_id);
289 }
290 }
291 fn encode_field_4<B: BufMut>(&self, buf: &mut B, version: i16, _flex: bool) {
292 if version >= 1 {
293 put_uuid(buf, self.voter_directory_id);
294 }
295 }
296 fn encode_field_5<B: BufMut>(&self, buf: &mut B, version: i16, _flex: bool) {
297 if version >= 0 {
298 put_i32(buf, self.last_offset_epoch);
299 }
300 }
301 fn encode_field_6<B: BufMut>(&self, buf: &mut B, version: i16, _flex: bool) {
302 if version >= 0 {
303 put_i64(buf, self.last_offset);
304 }
305 }
306 fn encode_field_7<B: BufMut>(&self, buf: &mut B, version: i16, _flex: bool) {
307 if version >= 2 {
308 put_bool(buf, self.pre_vote);
309 }
310 }
311 fn encode_tagged_fields<B: BufMut>(
312 &self,
313 buf: &mut B,
314 _version: i16,
315 flex: bool,
316 ) -> Result<(), ProtocolError> {
317 if flex {
318 let tagged = WriteTaggedFields::new();
319 tagged.write(buf, &self.unknown_tagged_fields)?;
320 }
321 Ok(())
322 }
323 fn decode_field_0<B: Buf>(
324 out: &mut Self,
325 buf: &mut B,
326 version: i16,
327 _flex: bool,
328 ) -> Result<(), ProtocolError> {
329 if version >= 0 {
330 out.partition_index = get_i32(buf)?;
331 }
332 Ok(())
333 }
334 fn decode_field_1<B: Buf>(
335 out: &mut Self,
336 buf: &mut B,
337 version: i16,
338 _flex: bool,
339 ) -> Result<(), ProtocolError> {
340 if version >= 0 {
341 out.replica_epoch = get_i32(buf)?;
342 }
343 Ok(())
344 }
345 fn decode_field_2<B: Buf>(
346 out: &mut Self,
347 buf: &mut B,
348 version: i16,
349 _flex: bool,
350 ) -> Result<(), ProtocolError> {
351 if version >= 0 {
352 out.replica_id = get_i32(buf)?;
353 }
354 Ok(())
355 }
356 fn decode_field_3<B: Buf>(
357 out: &mut Self,
358 buf: &mut B,
359 version: i16,
360 _flex: bool,
361 ) -> Result<(), ProtocolError> {
362 if version >= 1 {
363 out.replica_directory_id = get_uuid(buf)?;
364 }
365 Ok(())
366 }
367 fn decode_field_4<B: Buf>(
368 out: &mut Self,
369 buf: &mut B,
370 version: i16,
371 _flex: bool,
372 ) -> Result<(), ProtocolError> {
373 if version >= 1 {
374 out.voter_directory_id = get_uuid(buf)?;
375 }
376 Ok(())
377 }
378 fn decode_field_5<B: Buf>(
379 out: &mut Self,
380 buf: &mut B,
381 version: i16,
382 _flex: bool,
383 ) -> Result<(), ProtocolError> {
384 if version >= 0 {
385 out.last_offset_epoch = get_i32(buf)?;
386 }
387 Ok(())
388 }
389 fn decode_field_6<B: Buf>(
390 out: &mut Self,
391 buf: &mut B,
392 version: i16,
393 _flex: bool,
394 ) -> Result<(), ProtocolError> {
395 if version >= 0 {
396 out.last_offset = get_i64(buf)?;
397 }
398 Ok(())
399 }
400 fn decode_field_7<B: Buf>(
401 out: &mut Self,
402 buf: &mut B,
403 version: i16,
404 _flex: bool,
405 ) -> Result<(), ProtocolError> {
406 if version >= 2 {
407 out.pre_vote = get_bool(buf)?;
408 }
409 Ok(())
410 }
411 fn decode_tagged_fields<B: Buf>(
412 out: &mut Self,
413 buf: &mut B,
414 _version: i16,
415 flex: bool,
416 ) -> Result<(), ProtocolError> {
417 if flex {
418 out.unknown_tagged_fields = read_tagged_fields(buf, |_tag, _payload| Ok(false))?;
419 }
420 Ok(())
421 }
422}
423impl Encode for PartitionData {
424 fn encode<B: BufMut>(&self, buf: &mut B, version: i16) -> Result<(), ProtocolError> {
425 let flex = version >= 0;
426 self.encode_field_0(buf, version, flex);
427 self.encode_field_1(buf, version, flex);
428 self.encode_field_2(buf, version, flex);
429 self.encode_field_3(buf, version, flex);
430 self.encode_field_4(buf, version, flex);
431 self.encode_field_5(buf, version, flex);
432 self.encode_field_6(buf, version, flex);
433 self.encode_field_7(buf, version, flex);
434 self.encode_tagged_fields(buf, version, flex)?;
435 Ok(())
436 }
437 fn encoded_len(&self, version: i16) -> usize {
438 let flex = version >= 0;
439 let mut n: usize = 0;
440 if version >= 0 {
441 n += 4;
442 }
443 if version >= 0 {
444 n += 4;
445 }
446 if version >= 0 {
447 n += 4;
448 }
449 if version >= 1 {
450 n += 16;
451 }
452 if version >= 1 {
453 n += 16;
454 }
455 if version >= 0 {
456 n += 4;
457 }
458 if version >= 0 {
459 n += 8;
460 }
461 if version >= 2 {
462 n += 1;
463 }
464 if flex {
465 let known_pairs: Vec<(u32, usize)> = Vec::new();
466 n += tagged_fields_len(&known_pairs, &self.unknown_tagged_fields);
467 }
468 n
469 }
470}
471impl Decode<'_> for PartitionData {
472 fn decode<B: Buf>(buf: &mut B, version: i16) -> Result<Self, ProtocolError> {
473 let flex = version >= 0;
474 let mut out = Self::default();
475 Self::decode_field_0(&mut out, buf, version, flex)?;
476 Self::decode_field_1(&mut out, buf, version, flex)?;
477 Self::decode_field_2(&mut out, buf, version, flex)?;
478 Self::decode_field_3(&mut out, buf, version, flex)?;
479 Self::decode_field_4(&mut out, buf, version, flex)?;
480 Self::decode_field_5(&mut out, buf, version, flex)?;
481 Self::decode_field_6(&mut out, buf, version, flex)?;
482 Self::decode_field_7(&mut out, buf, version, flex)?;
483 Self::decode_tagged_fields(&mut out, buf, version, flex)?;
484 Ok(out)
485 }
486}
487#[cfg(test)]
488impl PartitionData {
489 #[must_use]
490 pub fn populated(version: i16) -> Self {
491 let mut m = Self::default();
492 if version >= 0 {
493 m.partition_index = 1i32;
494 }
495 if version >= 0 {
496 m.replica_epoch = 1i32;
497 }
498 if version >= 0 {
499 m.replica_id = 1i32;
500 }
501 if version >= 1 {
502 m.replica_directory_id = Uuid([1u8; 16]);
503 }
504 if version >= 1 {
505 m.voter_directory_id = Uuid([1u8; 16]);
506 }
507 if version >= 0 {
508 m.last_offset_epoch = 1i32;
509 }
510 if version >= 0 {
511 m.last_offset = 1i64;
512 }
513 if version >= 2 {
514 m.pre_vote = true;
515 }
516 m
517 }
518}
519#[must_use]
522#[allow(unused_comparisons)]
523pub fn default_json(version: i16) -> ::serde_json::Value {
524 let mut obj = ::serde_json::Map::new();
525 obj.insert("clusterId".to_owned(), ::serde_json::Value::Null);
526 if version >= 1 {
527 obj.insert("voterId".to_owned(), ::serde_json::json!(-1));
528 }
529 obj.insert("topics".to_owned(), ::serde_json::Value::Array(vec![]));
530 ::serde_json::Value::Object(obj)
531}
532impl crate::ProtocolRequest for VoteRequest {
533 const API_KEY: i16 = API_KEY;
534 const MIN_VERSION: i16 = MIN_VERSION;
535 const MAX_VERSION: i16 = MAX_VERSION;
536 const LATEST_STABLE_VERSION: i16 = LATEST_STABLE_VERSION;
537 const FLEXIBLE_MIN: i16 = FLEXIBLE_MIN;
538 type Response = super::vote_response::VoteResponse;
539}