1use bytes::BufMut;
3
4use crate::{
5 DecodeBorrow, Encode, ProtocolError, UnknownTaggedFields,
6 primitives::{
7 fixed::{get_i32, get_u16, put_i32, put_u16},
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 = 54;
21pub const MIN_VERSION: i16 = 0;
22pub const MAX_VERSION: i16 = 1;
23pub const LATEST_STABLE_VERSION: i16 = 1;
24pub const FLEXIBLE_MIN: i16 = 1;
25#[inline]
26#[must_use]
27pub fn is_flexible(version: i16) -> bool {
28 version >= FLEXIBLE_MIN
29}
30#[derive(Debug, Clone, PartialEq, Eq, Default)]
31pub struct EndQuorumEpochRequest<'a> {
32 pub cluster_id: Option<&'a str>,
33 pub topics: Vec<TopicData<'a>>,
34 pub leader_endpoints: Vec<LeaderEndpoint<'a>>,
35 pub unknown_tagged_fields: UnknownTaggedFields,
36}
37impl EndQuorumEpochRequest<'_> {
38 #[must_use]
42 pub fn to_owned(&self) -> crate::owned::end_quorum_epoch_request::EndQuorumEpochRequest {
43 crate::owned::end_quorum_epoch_request::EndQuorumEpochRequest {
44 cluster_id: (self.cluster_id).map(std::string::ToString::to_string),
45 topics: (self.topics).iter().map(TopicData::to_owned).collect(),
46 leader_endpoints: (self.leader_endpoints)
47 .iter()
48 .map(LeaderEndpoint::to_owned)
49 .collect(),
50 unknown_tagged_fields: self.unknown_tagged_fields.clone(),
51 }
52 }
53}
54impl Encode for EndQuorumEpochRequest<'_> {
55 fn encode<B: BufMut>(&self, buf: &mut B, version: i16) -> Result<(), ProtocolError> {
56 if !(MIN_VERSION..=MAX_VERSION).contains(&version) {
57 return Err(ProtocolError::UnsupportedVersion {
58 api_key: API_KEY,
59 version,
60 });
61 }
62 let flex = is_flexible(version);
63 if version >= 0 {
64 if flex {
65 let () = put_compact_nullable_string(buf, self.cluster_id);
66 } else {
67 let () = put_nullable_string(buf, self.cluster_id);
68 }
69 }
70 if version >= 0 {
71 {
72 crate::primitives::array::put_array_len(buf, (self.topics).len(), flex);
73 for it in &self.topics {
74 it.encode(buf, version)?;
75 }
76 };
77 }
78 if version >= 1 {
79 {
80 crate::primitives::array::put_array_len(buf, (self.leader_endpoints).len(), flex);
81 for it in &self.leader_endpoints {
82 it.encode(buf, version)?;
83 }
84 };
85 }
86 if flex {
87 let tagged = WriteTaggedFields::new();
88 tagged.write(buf, &self.unknown_tagged_fields);
89 }
90 Ok(())
91 }
92 fn encoded_len(&self, version: i16) -> usize {
93 let flex = is_flexible(version);
94 let mut n: usize = 0;
95 if version >= 0 {
96 n += if flex {
97 compact_nullable_string_len(self.cluster_id)
98 } else {
99 nullable_string_len(self.cluster_id)
100 };
101 }
102 if version >= 0 {
103 n += {
104 let prefix =
105 crate::primitives::array::array_len_prefix_len((self.topics).len(), flex);
106 let body: usize = (self.topics).iter().map(|it| it.encoded_len(version)).sum();
107 prefix + body
108 };
109 }
110 if version >= 1 {
111 n += {
112 let prefix = crate::primitives::array::array_len_prefix_len(
113 (self.leader_endpoints).len(),
114 flex,
115 );
116 let body: usize = (self.leader_endpoints)
117 .iter()
118 .map(|it| it.encoded_len(version))
119 .sum();
120 prefix + body
121 };
122 }
123 if flex {
124 let known_pairs: Vec<(u32, usize)> = Vec::new();
125 n += tagged_fields_len(&known_pairs, &self.unknown_tagged_fields);
126 }
127 n
128 }
129}
130impl<'de> DecodeBorrow<'de> for EndQuorumEpochRequest<'de> {
131 fn decode_borrow(buf: &mut &'de [u8], version: i16) -> Result<Self, ProtocolError> {
132 if !(MIN_VERSION..=MAX_VERSION).contains(&version) {
133 return Err(ProtocolError::UnsupportedVersion {
134 api_key: API_KEY,
135 version,
136 });
137 }
138 let flex = is_flexible(version);
139 let mut out = Self::default();
140 if version >= 0 {
141 out.cluster_id = if flex {
142 get_compact_nullable_string_borrowed(buf)?
143 } else {
144 get_nullable_string_borrowed(buf)?
145 };
146 }
147 if version >= 0 {
148 out.topics = {
149 let n = crate::primitives::array::get_array_len(buf, flex)?;
150 let mut v = Vec::with_capacity(n);
151 for _ in 0..n {
152 v.push(TopicData::decode_borrow(buf, version)?);
153 }
154 v
155 };
156 }
157 if version >= 1 {
158 out.leader_endpoints = {
159 let n = crate::primitives::array::get_array_len(buf, flex)?;
160 let mut v = Vec::with_capacity(n);
161 for _ in 0..n {
162 v.push(LeaderEndpoint::decode_borrow(buf, version)?);
163 }
164 v
165 };
166 }
167 if flex {
168 out.unknown_tagged_fields = read_tagged_fields(buf, |_tag, _payload| Ok(false))?;
169 }
170 Ok(out)
171 }
172}
173#[cfg(test)]
174impl EndQuorumEpochRequest<'_> {
175 #[must_use]
176 pub fn populated(version: i16) -> Self {
177 let mut m = Self::default();
178 if version >= 0 {
179 m.cluster_id = Some("x");
180 }
181 if version >= 0 {
182 m.topics = vec![TopicData::populated(version)];
183 }
184 if version >= 1 {
185 m.leader_endpoints = vec![LeaderEndpoint::populated(version)];
186 }
187 m
188 }
189}
190#[derive(Debug, Clone, PartialEq, Eq, Default)]
191pub struct TopicData<'a> {
192 pub topic_name: &'a str,
193 pub partitions: Vec<PartitionData>,
194 pub unknown_tagged_fields: UnknownTaggedFields,
195}
196impl TopicData<'_> {
197 #[must_use]
201 pub fn to_owned(&self) -> crate::owned::end_quorum_epoch_request::TopicData {
202 crate::owned::end_quorum_epoch_request::TopicData {
203 topic_name: (self.topic_name).to_string(),
204 partitions: (self.partitions)
205 .iter()
206 .map(PartitionData::to_owned)
207 .collect(),
208 unknown_tagged_fields: self.unknown_tagged_fields.clone(),
209 }
210 }
211}
212impl Encode for TopicData<'_> {
213 fn encode<B: BufMut>(&self, buf: &mut B, version: i16) -> Result<(), ProtocolError> {
214 let flex = version >= 1;
215 if version >= 0 {
216 if flex {
217 let () = put_compact_string(buf, self.topic_name);
218 } else {
219 let () = put_string(buf, self.topic_name);
220 }
221 }
222 if version >= 0 {
223 {
224 crate::primitives::array::put_array_len(buf, (self.partitions).len(), flex);
225 for it in &self.partitions {
226 it.encode(buf, version)?;
227 }
228 };
229 }
230 if flex {
231 let tagged = WriteTaggedFields::new();
232 tagged.write(buf, &self.unknown_tagged_fields);
233 }
234 Ok(())
235 }
236 fn encoded_len(&self, version: i16) -> usize {
237 let flex = version >= 1;
238 let mut n: usize = 0;
239 if version >= 0 {
240 n += if flex {
241 compact_string_len(self.topic_name)
242 } else {
243 string_len(self.topic_name)
244 };
245 }
246 if version >= 0 {
247 n += {
248 let prefix =
249 crate::primitives::array::array_len_prefix_len((self.partitions).len(), flex);
250 let body: usize = (self.partitions)
251 .iter()
252 .map(|it| it.encoded_len(version))
253 .sum();
254 prefix + body
255 };
256 }
257 if flex {
258 let known_pairs: Vec<(u32, usize)> = Vec::new();
259 n += tagged_fields_len(&known_pairs, &self.unknown_tagged_fields);
260 }
261 n
262 }
263}
264impl<'de> DecodeBorrow<'de> for TopicData<'de> {
265 fn decode_borrow(buf: &mut &'de [u8], version: i16) -> Result<Self, ProtocolError> {
266 let flex = version >= 1;
267 let mut out = Self::default();
268 if version >= 0 {
269 out.topic_name = if flex {
270 get_compact_string_borrowed(buf)?
271 } else {
272 get_string_borrowed(buf)?
273 };
274 }
275 if version >= 0 {
276 out.partitions = {
277 let n = crate::primitives::array::get_array_len(buf, flex)?;
278 let mut v = Vec::with_capacity(n);
279 for _ in 0..n {
280 v.push(PartitionData::decode_borrow(buf, version)?);
281 }
282 v
283 };
284 }
285 if flex {
286 out.unknown_tagged_fields = read_tagged_fields(buf, |_tag, _payload| Ok(false))?;
287 }
288 Ok(out)
289 }
290}
291#[cfg(test)]
292impl TopicData<'_> {
293 #[must_use]
294 pub fn populated(version: i16) -> Self {
295 let mut m = Self::default();
296 if version >= 0 {
297 m.topic_name = "x";
298 }
299 if version >= 0 {
300 m.partitions = vec![PartitionData::populated(version)];
301 }
302 m
303 }
304}
305#[derive(Debug, Clone, PartialEq, Eq, Default)]
306pub struct PartitionData {
307 pub partition_index: i32,
308 pub leader_id: i32,
309 pub leader_epoch: i32,
310 pub preferred_successors: Vec<i32>,
311 pub preferred_candidates: Vec<ReplicaInfo>,
312 pub unknown_tagged_fields: UnknownTaggedFields,
313}
314impl PartitionData {
315 #[must_use]
319 pub fn to_owned(&self) -> crate::owned::end_quorum_epoch_request::PartitionData {
320 crate::owned::end_quorum_epoch_request::PartitionData {
321 partition_index: (self.partition_index),
322 leader_id: (self.leader_id),
323 leader_epoch: (self.leader_epoch),
324 preferred_successors: (self.preferred_successors).clone(),
325 preferred_candidates: (self.preferred_candidates)
326 .iter()
327 .map(ReplicaInfo::to_owned)
328 .collect(),
329 unknown_tagged_fields: self.unknown_tagged_fields.clone(),
330 }
331 }
332}
333impl Encode for PartitionData {
334 fn encode<B: BufMut>(&self, buf: &mut B, version: i16) -> Result<(), ProtocolError> {
335 let flex = version >= 1;
336 if version >= 0 {
337 put_i32(buf, self.partition_index);
338 }
339 if version >= 0 {
340 put_i32(buf, self.leader_id);
341 }
342 if version >= 0 {
343 put_i32(buf, self.leader_epoch);
344 }
345 if version == 0 {
346 {
347 crate::primitives::array::put_array_len(
348 buf,
349 (self.preferred_successors).len(),
350 flex,
351 );
352 for it in &self.preferred_successors {
353 put_i32(buf, *it);
354 }
355 };
356 }
357 if version >= 1 {
358 {
359 crate::primitives::array::put_array_len(
360 buf,
361 (self.preferred_candidates).len(),
362 flex,
363 );
364 for it in &self.preferred_candidates {
365 it.encode(buf, version)?;
366 }
367 };
368 }
369 if flex {
370 let tagged = WriteTaggedFields::new();
371 tagged.write(buf, &self.unknown_tagged_fields);
372 }
373 Ok(())
374 }
375 fn encoded_len(&self, version: i16) -> usize {
376 let flex = version >= 1;
377 let mut n: usize = 0;
378 if version >= 0 {
379 n += 4;
380 }
381 if version >= 0 {
382 n += 4;
383 }
384 if version >= 0 {
385 n += 4;
386 }
387 if version == 0 {
388 n += {
389 let prefix = crate::primitives::array::array_len_prefix_len(
390 (self.preferred_successors).len(),
391 flex,
392 );
393 let body: usize = (self.preferred_successors).iter().map(|_| 4).sum();
394 prefix + body
395 };
396 }
397 if version >= 1 {
398 n += {
399 let prefix = crate::primitives::array::array_len_prefix_len(
400 (self.preferred_candidates).len(),
401 flex,
402 );
403 let body: usize = (self.preferred_candidates)
404 .iter()
405 .map(|it| it.encoded_len(version))
406 .sum();
407 prefix + body
408 };
409 }
410 if flex {
411 let known_pairs: Vec<(u32, usize)> = Vec::new();
412 n += tagged_fields_len(&known_pairs, &self.unknown_tagged_fields);
413 }
414 n
415 }
416}
417impl<'de> DecodeBorrow<'de> for PartitionData {
418 fn decode_borrow(buf: &mut &'de [u8], version: i16) -> Result<Self, ProtocolError> {
419 let flex = version >= 1;
420 let mut out = Self::default();
421 if version >= 0 {
422 out.partition_index = get_i32(buf)?;
423 }
424 if version >= 0 {
425 out.leader_id = get_i32(buf)?;
426 }
427 if version >= 0 {
428 out.leader_epoch = get_i32(buf)?;
429 }
430 if version == 0 {
431 out.preferred_successors = {
432 let n = crate::primitives::array::get_array_len(buf, flex)?;
433 let mut v = Vec::with_capacity(n);
434 for _ in 0..n {
435 v.push(get_i32(buf)?);
436 }
437 v
438 };
439 }
440 if version >= 1 {
441 out.preferred_candidates = {
442 let n = crate::primitives::array::get_array_len(buf, flex)?;
443 let mut v = Vec::with_capacity(n);
444 for _ in 0..n {
445 v.push(ReplicaInfo::decode_borrow(buf, version)?);
446 }
447 v
448 };
449 }
450 if flex {
451 out.unknown_tagged_fields = read_tagged_fields(buf, |_tag, _payload| Ok(false))?;
452 }
453 Ok(out)
454 }
455}
456#[cfg(test)]
457impl PartitionData {
458 #[must_use]
459 pub fn populated(version: i16) -> Self {
460 let mut m = Self::default();
461 if version >= 0 {
462 m.partition_index = 1i32;
463 }
464 if version >= 0 {
465 m.leader_id = 1i32;
466 }
467 if version >= 0 {
468 m.leader_epoch = 1i32;
469 }
470 if version == 0 {
471 m.preferred_successors = vec![1i32];
472 }
473 if version >= 1 {
474 m.preferred_candidates = vec![ReplicaInfo::populated(version)];
475 }
476 m
477 }
478}
479#[derive(Debug, Clone, PartialEq, Eq, Default)]
480pub struct ReplicaInfo {
481 pub candidate_id: i32,
482 pub candidate_directory_id: crate::primitives::uuid::Uuid,
483 pub unknown_tagged_fields: UnknownTaggedFields,
484}
485impl ReplicaInfo {
486 #[must_use]
490 pub fn to_owned(&self) -> crate::owned::end_quorum_epoch_request::ReplicaInfo {
491 crate::owned::end_quorum_epoch_request::ReplicaInfo {
492 candidate_id: (self.candidate_id),
493 candidate_directory_id: (self.candidate_directory_id),
494 unknown_tagged_fields: self.unknown_tagged_fields.clone(),
495 }
496 }
497}
498impl Encode for ReplicaInfo {
499 fn encode<B: BufMut>(&self, buf: &mut B, version: i16) -> Result<(), ProtocolError> {
500 let flex = version >= 1;
501 if version >= 1 {
502 put_i32(buf, self.candidate_id);
503 }
504 if version >= 1 {
505 crate::primitives::uuid::put_uuid(buf, self.candidate_directory_id);
506 }
507 if flex {
508 let tagged = WriteTaggedFields::new();
509 tagged.write(buf, &self.unknown_tagged_fields);
510 }
511 Ok(())
512 }
513 fn encoded_len(&self, version: i16) -> usize {
514 let flex = version >= 1;
515 let mut n: usize = 0;
516 if version >= 1 {
517 n += 4;
518 }
519 if version >= 1 {
520 n += 16;
521 }
522 if flex {
523 let known_pairs: Vec<(u32, usize)> = Vec::new();
524 n += tagged_fields_len(&known_pairs, &self.unknown_tagged_fields);
525 }
526 n
527 }
528}
529impl<'de> DecodeBorrow<'de> for ReplicaInfo {
530 fn decode_borrow(buf: &mut &'de [u8], version: i16) -> Result<Self, ProtocolError> {
531 let flex = version >= 1;
532 let mut out = Self::default();
533 if version >= 1 {
534 out.candidate_id = get_i32(buf)?;
535 }
536 if version >= 1 {
537 out.candidate_directory_id = crate::primitives::uuid::get_uuid(buf)?;
538 }
539 if flex {
540 out.unknown_tagged_fields = read_tagged_fields(buf, |_tag, _payload| Ok(false))?;
541 }
542 Ok(out)
543 }
544}
545#[cfg(test)]
546impl ReplicaInfo {
547 #[must_use]
548 pub fn populated(version: i16) -> Self {
549 let mut m = Self::default();
550 if version >= 1 {
551 m.candidate_id = 1i32;
552 }
553 if version >= 1 {
554 m.candidate_directory_id = crate::primitives::uuid::Uuid([1u8; 16]);
555 }
556 m
557 }
558}
559#[derive(Debug, Clone, PartialEq, Eq, Default)]
560pub struct LeaderEndpoint<'a> {
561 pub name: &'a str,
562 pub host: &'a str,
563 pub port: u16,
564 pub unknown_tagged_fields: UnknownTaggedFields,
565}
566impl LeaderEndpoint<'_> {
567 #[must_use]
571 pub fn to_owned(&self) -> crate::owned::end_quorum_epoch_request::LeaderEndpoint {
572 crate::owned::end_quorum_epoch_request::LeaderEndpoint {
573 name: (self.name).to_string(),
574 host: (self.host).to_string(),
575 port: (self.port),
576 unknown_tagged_fields: self.unknown_tagged_fields.clone(),
577 }
578 }
579}
580impl Encode for LeaderEndpoint<'_> {
581 fn encode<B: BufMut>(&self, buf: &mut B, version: i16) -> Result<(), ProtocolError> {
582 let flex = version >= 1;
583 if version >= 1 {
584 if flex {
585 let () = put_compact_string(buf, self.name);
586 } else {
587 let () = put_string(buf, self.name);
588 }
589 }
590 if version >= 1 {
591 if flex {
592 let () = put_compact_string(buf, self.host);
593 } else {
594 let () = put_string(buf, self.host);
595 }
596 }
597 if version >= 1 {
598 put_u16(buf, self.port);
599 }
600 if flex {
601 let tagged = WriteTaggedFields::new();
602 tagged.write(buf, &self.unknown_tagged_fields);
603 }
604 Ok(())
605 }
606 fn encoded_len(&self, version: i16) -> usize {
607 let flex = version >= 1;
608 let mut n: usize = 0;
609 if version >= 1 {
610 n += if flex {
611 compact_string_len(self.name)
612 } else {
613 string_len(self.name)
614 };
615 }
616 if version >= 1 {
617 n += if flex {
618 compact_string_len(self.host)
619 } else {
620 string_len(self.host)
621 };
622 }
623 if version >= 1 {
624 n += 2;
625 }
626 if flex {
627 let known_pairs: Vec<(u32, usize)> = Vec::new();
628 n += tagged_fields_len(&known_pairs, &self.unknown_tagged_fields);
629 }
630 n
631 }
632}
633impl<'de> DecodeBorrow<'de> for LeaderEndpoint<'de> {
634 fn decode_borrow(buf: &mut &'de [u8], version: i16) -> Result<Self, ProtocolError> {
635 let flex = version >= 1;
636 let mut out = Self::default();
637 if version >= 1 {
638 out.name = if flex {
639 get_compact_string_borrowed(buf)?
640 } else {
641 get_string_borrowed(buf)?
642 };
643 }
644 if version >= 1 {
645 out.host = if flex {
646 get_compact_string_borrowed(buf)?
647 } else {
648 get_string_borrowed(buf)?
649 };
650 }
651 if version >= 1 {
652 out.port = get_u16(buf)?;
653 }
654 if flex {
655 out.unknown_tagged_fields = read_tagged_fields(buf, |_tag, _payload| Ok(false))?;
656 }
657 Ok(out)
658 }
659}
660#[cfg(test)]
661impl LeaderEndpoint<'_> {
662 #[must_use]
663 pub fn populated(version: i16) -> Self {
664 let mut m = Self::default();
665 if version >= 1 {
666 m.name = "x";
667 }
668 if version >= 1 {
669 m.host = "x";
670 }
671 if version >= 1 {
672 m.port = 1u16;
673 }
674 m
675 }
676}