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