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