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