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