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