1use bytes::BufMut;
3
4use crate::{
5 DecodeBorrow, Encode, ProtocolError, UnknownTaggedFields,
6 owned::metadata_response,
7 primitives::{
8 array::{array_len_prefix_len, get_array_len, put_array_len},
9 fixed::{get_bool, get_i16, get_i32, put_bool, put_i16, put_i32},
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 = 3;
24pub const MIN_VERSION: i16 = 0;
25pub const MAX_VERSION: i16 = 13;
26pub const FLEXIBLE_MIN: i16 = 9;
27#[inline]
28#[must_use]
29pub fn is_flexible(version: i16) -> bool {
30 version >= FLEXIBLE_MIN
31}
32#[derive(Debug, Clone, PartialEq, Eq)]
33pub struct MetadataResponse<'a> {
34 pub throttle_time_ms: i32,
35 pub brokers: Vec<MetadataResponseBroker<'a>>,
36 pub cluster_id: Option<&'a str>,
37 pub controller_id: i32,
38 pub topics: Vec<MetadataResponseTopic<'a>>,
39 pub cluster_authorized_operations: i32,
40 pub error_code: i16,
41 pub unknown_tagged_fields: UnknownTaggedFields,
42}
43impl Default for MetadataResponse<'_> {
44 fn default() -> Self {
45 Self {
46 throttle_time_ms: 0i32,
47 brokers: Vec::new(),
48 cluster_id: None,
49 controller_id: -1i32,
50 topics: Vec::new(),
51 cluster_authorized_operations: -2_147_483_648i32,
52 error_code: 0i16,
53 unknown_tagged_fields: UnknownTaggedFields::default(),
54 }
55 }
56}
57impl MetadataResponse<'_> {
58 #[must_use]
59 pub fn to_owned(&self) -> metadata_response::MetadataResponse {
60 metadata_response::MetadataResponse {
61 throttle_time_ms: (self.throttle_time_ms),
62 brokers: (self.brokers)
63 .iter()
64 .map(MetadataResponseBroker::to_owned)
65 .collect(),
66 cluster_id: (self.cluster_id).map(str::to_owned),
67 controller_id: (self.controller_id),
68 topics: (self.topics)
69 .iter()
70 .map(MetadataResponseTopic::to_owned)
71 .collect(),
72 cluster_authorized_operations: (self.cluster_authorized_operations),
73 error_code: (self.error_code),
74 unknown_tagged_fields: self.unknown_tagged_fields.clone(),
75 }
76 }
77}
78impl Encode for MetadataResponse<'_> {
79 fn encode<B: BufMut>(&self, buf: &mut B, version: i16) -> Result<(), ProtocolError> {
80 if !(MIN_VERSION..=MAX_VERSION).contains(&version) {
81 return Err(ProtocolError::UnsupportedVersion {
82 api_key: API_KEY,
83 version,
84 });
85 }
86 let flex = is_flexible(version);
87 if version >= 3 {
88 put_i32(buf, self.throttle_time_ms);
89 }
90 if version >= 0 {
91 {
92 put_array_len(buf, (self.brokers).len(), flex)?;
93 for it in &self.brokers {
94 it.encode(buf, version)?;
95 }
96 }
97 }
98 if version >= 2 {
99 if flex {
100 put_compact_nullable_string(buf, self.cluster_id)?;
101 } else {
102 put_nullable_string(buf, self.cluster_id)?;
103 }
104 }
105 if version >= 1 {
106 put_i32(buf, self.controller_id);
107 }
108 if version >= 0 {
109 {
110 put_array_len(buf, (self.topics).len(), flex)?;
111 for it in &self.topics {
112 it.encode(buf, version)?;
113 }
114 }
115 }
116 if (8..=10).contains(&version) {
117 put_i32(buf, self.cluster_authorized_operations);
118 }
119 if version >= 13 {
120 put_i16(buf, self.error_code);
121 }
122 if flex {
123 let tagged = WriteTaggedFields::new();
124 tagged.write(buf, &self.unknown_tagged_fields)?;
125 }
126 Ok(())
127 }
128 fn encoded_len(&self, version: i16) -> usize {
129 let flex = is_flexible(version);
130 let mut n: usize = 0;
131 if version >= 3 {
132 n += 4;
133 }
134 if version >= 0 {
135 n += {
136 let prefix = array_len_prefix_len((self.brokers).len(), flex);
137 let body: usize = (self.brokers)
138 .iter()
139 .map(|it| it.encoded_len(version))
140 .sum();
141 prefix + body
142 };
143 }
144 if version >= 2 {
145 n += if flex {
146 compact_nullable_string_len(self.cluster_id)
147 } else {
148 nullable_string_len(self.cluster_id)
149 };
150 }
151 if version >= 1 {
152 n += 4;
153 }
154 if version >= 0 {
155 n += {
156 let prefix = array_len_prefix_len((self.topics).len(), flex);
157 let body: usize = (self.topics).iter().map(|it| it.encoded_len(version)).sum();
158 prefix + body
159 };
160 }
161 if (8..=10).contains(&version) {
162 n += 4;
163 }
164 if version >= 13 {
165 n += 2;
166 }
167 if flex {
168 let known_pairs: Vec<(u32, usize)> = Vec::new();
169 n += tagged_fields_len(&known_pairs, &self.unknown_tagged_fields);
170 }
171 n
172 }
173}
174impl<'de> DecodeBorrow<'de> for MetadataResponse<'de> {
175 fn decode_borrow(buf: &mut &'de [u8], version: i16) -> Result<Self, ProtocolError> {
176 if !(MIN_VERSION..=MAX_VERSION).contains(&version) {
177 return Err(ProtocolError::UnsupportedVersion {
178 api_key: API_KEY,
179 version,
180 });
181 }
182 let flex = is_flexible(version);
183 let mut out = Self::default();
184 if version >= 3 {
185 out.throttle_time_ms = get_i32(buf)?;
186 }
187 if version >= 0 {
188 out.brokers = {
189 let n = get_array_len(buf, flex)?;
190 let mut v = Vec::with_capacity(n);
191 for _ in 0..n {
192 v.push(MetadataResponseBroker::decode_borrow(buf, version)?);
193 }
194 v
195 };
196 }
197 if version >= 2 {
198 out.cluster_id = if flex {
199 get_compact_nullable_string_borrowed(buf)?
200 } else {
201 get_nullable_string_borrowed(buf)?
202 };
203 }
204 if version >= 1 {
205 out.controller_id = get_i32(buf)?;
206 }
207 if version >= 0 {
208 out.topics = {
209 let n = get_array_len(buf, flex)?;
210 let mut v = Vec::with_capacity(n);
211 for _ in 0..n {
212 v.push(MetadataResponseTopic::decode_borrow(buf, version)?);
213 }
214 v
215 };
216 }
217 if (8..=10).contains(&version) {
218 out.cluster_authorized_operations = get_i32(buf)?;
219 }
220 if version >= 13 {
221 out.error_code = get_i16(buf)?;
222 }
223 if flex {
224 out.unknown_tagged_fields = read_tagged_fields(buf, |_tag, _payload| Ok(false))?;
225 }
226 Ok(out)
227 }
228}
229#[cfg(test)]
230impl MetadataResponse<'_> {
231 #[must_use]
232 pub fn populated(version: i16) -> Self {
233 let mut m = Self::default();
234 if version >= 3 {
235 m.throttle_time_ms = 1i32;
236 }
237 if version >= 0 {
238 m.brokers = vec![MetadataResponseBroker::populated(version)];
239 }
240 if version >= 2 {
241 m.cluster_id = Some("x");
242 }
243 if version >= 1 {
244 m.controller_id = 1i32;
245 }
246 if version >= 0 {
247 m.topics = vec![MetadataResponseTopic::populated(version)];
248 }
249 if (8..=10).contains(&version) {
250 m.cluster_authorized_operations = 1i32;
251 }
252 if version >= 13 {
253 m.error_code = 1i16;
254 }
255 m
256 }
257}
258#[derive(Debug, Clone, PartialEq, Eq, Default)]
259pub struct MetadataResponseBroker<'a> {
260 pub node_id: i32,
261 pub host: &'a str,
262 pub port: i32,
263 pub rack: Option<&'a str>,
264 pub unknown_tagged_fields: UnknownTaggedFields,
265}
266impl MetadataResponseBroker<'_> {
267 #[must_use]
268 pub fn to_owned(&self) -> metadata_response::MetadataResponseBroker {
269 metadata_response::MetadataResponseBroker {
270 node_id: (self.node_id),
271 host: (self.host).to_owned(),
272 port: (self.port),
273 rack: (self.rack).map(str::to_owned),
274 unknown_tagged_fields: self.unknown_tagged_fields.clone(),
275 }
276 }
277}
278impl Encode for MetadataResponseBroker<'_> {
279 fn encode<B: BufMut>(&self, buf: &mut B, version: i16) -> Result<(), ProtocolError> {
280 let flex = version >= 9;
281 if version >= 0 {
282 put_i32(buf, self.node_id);
283 }
284 if version >= 0 {
285 if flex {
286 put_compact_string(buf, self.host)?;
287 } else {
288 put_string(buf, self.host)?;
289 }
290 }
291 if version >= 0 {
292 put_i32(buf, self.port);
293 }
294 if version >= 1 {
295 if flex {
296 put_compact_nullable_string(buf, self.rack)?;
297 } else {
298 put_nullable_string(buf, self.rack)?;
299 }
300 }
301 if flex {
302 let tagged = WriteTaggedFields::new();
303 tagged.write(buf, &self.unknown_tagged_fields)?;
304 }
305 Ok(())
306 }
307 fn encoded_len(&self, version: i16) -> usize {
308 let flex = version >= 9;
309 let mut n: usize = 0;
310 if version >= 0 {
311 n += 4;
312 }
313 if version >= 0 {
314 n += if flex {
315 compact_string_len(self.host)
316 } else {
317 string_len(self.host)
318 };
319 }
320 if version >= 0 {
321 n += 4;
322 }
323 if version >= 1 {
324 n += if flex {
325 compact_nullable_string_len(self.rack)
326 } else {
327 nullable_string_len(self.rack)
328 };
329 }
330 if flex {
331 let known_pairs: Vec<(u32, usize)> = Vec::new();
332 n += tagged_fields_len(&known_pairs, &self.unknown_tagged_fields);
333 }
334 n
335 }
336}
337impl<'de> DecodeBorrow<'de> for MetadataResponseBroker<'de> {
338 fn decode_borrow(buf: &mut &'de [u8], version: i16) -> Result<Self, ProtocolError> {
339 let flex = version >= 9;
340 let mut out = Self::default();
341 if version >= 0 {
342 out.node_id = get_i32(buf)?;
343 }
344 if version >= 0 {
345 out.host = if flex {
346 get_compact_string_borrowed(buf)?
347 } else {
348 get_string_borrowed(buf)?
349 };
350 }
351 if version >= 0 {
352 out.port = get_i32(buf)?;
353 }
354 if version >= 1 {
355 out.rack = if flex {
356 get_compact_nullable_string_borrowed(buf)?
357 } else {
358 get_nullable_string_borrowed(buf)?
359 };
360 }
361 if flex {
362 out.unknown_tagged_fields = read_tagged_fields(buf, |_tag, _payload| Ok(false))?;
363 }
364 Ok(out)
365 }
366}
367#[cfg(test)]
368impl MetadataResponseBroker<'_> {
369 #[must_use]
370 pub fn populated(version: i16) -> Self {
371 let mut m = Self::default();
372 if version >= 0 {
373 m.node_id = 1i32;
374 }
375 if version >= 0 {
376 m.host = "x";
377 }
378 if version >= 0 {
379 m.port = 1i32;
380 }
381 if version >= 1 {
382 m.rack = Some("x");
383 }
384 m
385 }
386}
387#[derive(Debug, Clone, PartialEq, Eq)]
388pub struct MetadataResponseTopic<'a> {
389 pub error_code: i16,
390 pub name: Option<&'a str>,
391 pub topic_id: Uuid,
392 pub is_internal: bool,
393 pub partitions: Vec<MetadataResponsePartition>,
394 pub topic_authorized_operations: i32,
395 pub unknown_tagged_fields: UnknownTaggedFields,
396}
397impl Default for MetadataResponseTopic<'_> {
398 fn default() -> Self {
399 Self {
400 error_code: 0i16,
401 name: Some(""),
402 topic_id: Uuid::default(),
403 is_internal: false,
404 partitions: Vec::new(),
405 topic_authorized_operations: -2_147_483_648i32,
406 unknown_tagged_fields: UnknownTaggedFields::default(),
407 }
408 }
409}
410impl MetadataResponseTopic<'_> {
411 #[must_use]
412 pub fn to_owned(&self) -> metadata_response::MetadataResponseTopic {
413 metadata_response::MetadataResponseTopic {
414 error_code: (self.error_code),
415 name: (self.name).map(str::to_owned),
416 topic_id: (self.topic_id),
417 is_internal: (self.is_internal),
418 partitions: (self.partitions)
419 .iter()
420 .map(MetadataResponsePartition::to_owned)
421 .collect(),
422 topic_authorized_operations: (self.topic_authorized_operations),
423 unknown_tagged_fields: self.unknown_tagged_fields.clone(),
424 }
425 }
426}
427impl Encode for MetadataResponseTopic<'_> {
428 fn encode<B: BufMut>(&self, buf: &mut B, version: i16) -> Result<(), ProtocolError> {
429 let flex = version >= 9;
430 if version >= 0 {
431 put_i16(buf, self.error_code);
432 }
433 if version >= 0 {
434 if version >= 12 {
435 if flex {
436 put_compact_nullable_string(buf, self.name)?;
437 } else {
438 put_nullable_string(buf, self.name)?;
439 }
440 } else {
441 if flex {
442 put_compact_string(buf, (self.name).unwrap_or(""))?;
443 } else {
444 put_string(buf, (self.name).unwrap_or(""))?;
445 }
446 }
447 }
448 if version >= 10 {
449 put_uuid(buf, self.topic_id);
450 }
451 if version >= 1 {
452 put_bool(buf, self.is_internal);
453 }
454 if version >= 0 {
455 {
456 put_array_len(buf, (self.partitions).len(), flex)?;
457 for it in &self.partitions {
458 it.encode(buf, version)?;
459 }
460 }
461 }
462 if version >= 8 {
463 put_i32(buf, self.topic_authorized_operations);
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 >= 9;
473 let mut n: usize = 0;
474 if version >= 0 {
475 n += 2;
476 }
477 if version >= 0 {
478 n += if version >= 12 {
479 if flex {
480 compact_nullable_string_len(self.name)
481 } else {
482 nullable_string_len(self.name)
483 }
484 } else {
485 if flex {
486 compact_string_len((self.name).unwrap_or(""))
487 } else {
488 string_len((self.name).unwrap_or(""))
489 }
490 };
491 }
492 if version >= 10 {
493 n += 16;
494 }
495 if version >= 1 {
496 n += 1;
497 }
498 if version >= 0 {
499 n += {
500 let prefix = array_len_prefix_len((self.partitions).len(), flex);
501 let body: usize = (self.partitions)
502 .iter()
503 .map(|it| it.encoded_len(version))
504 .sum();
505 prefix + body
506 };
507 }
508 if version >= 8 {
509 n += 4;
510 }
511 if flex {
512 let known_pairs: Vec<(u32, usize)> = Vec::new();
513 n += tagged_fields_len(&known_pairs, &self.unknown_tagged_fields);
514 }
515 n
516 }
517}
518impl<'de> DecodeBorrow<'de> for MetadataResponseTopic<'de> {
519 fn decode_borrow(buf: &mut &'de [u8], version: i16) -> Result<Self, ProtocolError> {
520 let flex = version >= 9;
521 let mut out = Self::default();
522 if version >= 0 {
523 out.error_code = get_i16(buf)?;
524 }
525 if version >= 0 {
526 out.name = if version >= 12 {
527 if flex {
528 get_compact_nullable_string_borrowed(buf)?
529 } else {
530 get_nullable_string_borrowed(buf)?
531 }
532 } else {
533 Some(if flex {
534 get_compact_string_borrowed(buf)?
535 } else {
536 get_string_borrowed(buf)?
537 })
538 };
539 }
540 if version >= 10 {
541 out.topic_id = get_uuid(buf)?;
542 }
543 if version >= 1 {
544 out.is_internal = get_bool(buf)?;
545 }
546 if version >= 0 {
547 out.partitions = {
548 let n = get_array_len(buf, flex)?;
549 let mut v = Vec::with_capacity(n);
550 for _ in 0..n {
551 v.push(MetadataResponsePartition::decode_borrow(buf, version)?);
552 }
553 v
554 };
555 }
556 if version >= 8 {
557 out.topic_authorized_operations = get_i32(buf)?;
558 }
559 if flex {
560 out.unknown_tagged_fields = read_tagged_fields(buf, |_tag, _payload| Ok(false))?;
561 }
562 Ok(out)
563 }
564}
565#[cfg(test)]
566impl MetadataResponseTopic<'_> {
567 #[must_use]
568 pub fn populated(version: i16) -> Self {
569 let mut m = Self::default();
570 if version >= 0 {
571 m.error_code = 1i16;
572 }
573 if version >= 0 {
574 m.name = Some("x");
575 }
576 if version >= 10 {
577 m.topic_id = Uuid([1u8; 16]);
578 }
579 if version >= 1 {
580 m.is_internal = true;
581 }
582 if version >= 0 {
583 m.partitions = vec![MetadataResponsePartition::populated(version)];
584 }
585 if version >= 8 {
586 m.topic_authorized_operations = 1i32;
587 }
588 m
589 }
590}
591#[derive(Debug, Clone, PartialEq, Eq)]
592pub struct MetadataResponsePartition {
593 pub error_code: i16,
594 pub partition_index: i32,
595 pub leader_id: i32,
596 pub leader_epoch: i32,
597 pub replica_nodes: Vec<i32>,
598 pub isr_nodes: Vec<i32>,
599 pub offline_replicas: Vec<i32>,
600 pub unknown_tagged_fields: UnknownTaggedFields,
601}
602impl Default for MetadataResponsePartition {
603 fn default() -> Self {
604 Self {
605 error_code: 0i16,
606 partition_index: 0i32,
607 leader_id: 0i32,
608 leader_epoch: -1i32,
609 replica_nodes: Vec::new(),
610 isr_nodes: Vec::new(),
611 offline_replicas: Vec::new(),
612 unknown_tagged_fields: UnknownTaggedFields::default(),
613 }
614 }
615}
616impl MetadataResponsePartition {
617 #[must_use]
618 pub fn to_owned(&self) -> metadata_response::MetadataResponsePartition {
619 metadata_response::MetadataResponsePartition {
620 error_code: (self.error_code),
621 partition_index: (self.partition_index),
622 leader_id: (self.leader_id),
623 leader_epoch: (self.leader_epoch),
624 replica_nodes: (self.replica_nodes).clone(),
625 isr_nodes: (self.isr_nodes).clone(),
626 offline_replicas: (self.offline_replicas).clone(),
627 unknown_tagged_fields: self.unknown_tagged_fields.clone(),
628 }
629 }
630}
631impl Encode for MetadataResponsePartition {
632 fn encode<B: BufMut>(&self, buf: &mut B, version: i16) -> Result<(), ProtocolError> {
633 let flex = version >= 9;
634 if version >= 0 {
635 put_i16(buf, self.error_code);
636 }
637 if version >= 0 {
638 put_i32(buf, self.partition_index);
639 }
640 if version >= 0 {
641 put_i32(buf, self.leader_id);
642 }
643 if version >= 7 {
644 put_i32(buf, self.leader_epoch);
645 }
646 if version >= 0 {
647 {
648 put_array_len(buf, (self.replica_nodes).len(), flex)?;
649 for it in &self.replica_nodes {
650 put_i32(buf, *it);
651 }
652 }
653 }
654 if version >= 0 {
655 {
656 put_array_len(buf, (self.isr_nodes).len(), flex)?;
657 for it in &self.isr_nodes {
658 put_i32(buf, *it);
659 }
660 }
661 }
662 if version >= 5 {
663 {
664 put_array_len(buf, (self.offline_replicas).len(), flex)?;
665 for it in &self.offline_replicas {
666 put_i32(buf, *it);
667 }
668 }
669 }
670 if flex {
671 let tagged = WriteTaggedFields::new();
672 tagged.write(buf, &self.unknown_tagged_fields)?;
673 }
674 Ok(())
675 }
676 fn encoded_len(&self, version: i16) -> usize {
677 let flex = version >= 9;
678 let mut n: usize = 0;
679 if version >= 0 {
680 n += 2;
681 }
682 if version >= 0 {
683 n += 4;
684 }
685 if version >= 0 {
686 n += 4;
687 }
688 if version >= 7 {
689 n += 4;
690 }
691 if version >= 0 {
692 n += {
693 let prefix = array_len_prefix_len((self.replica_nodes).len(), flex);
694 let body: usize = (self.replica_nodes).iter().map(|_| 4).sum();
695 prefix + body
696 };
697 }
698 if version >= 0 {
699 n += {
700 let prefix = array_len_prefix_len((self.isr_nodes).len(), flex);
701 let body: usize = (self.isr_nodes).iter().map(|_| 4).sum();
702 prefix + body
703 };
704 }
705 if version >= 5 {
706 n += {
707 let prefix = array_len_prefix_len((self.offline_replicas).len(), flex);
708 let body: usize = (self.offline_replicas).iter().map(|_| 4).sum();
709 prefix + body
710 };
711 }
712 if flex {
713 let known_pairs: Vec<(u32, usize)> = Vec::new();
714 n += tagged_fields_len(&known_pairs, &self.unknown_tagged_fields);
715 }
716 n
717 }
718}
719impl<'de> DecodeBorrow<'de> for MetadataResponsePartition {
720 fn decode_borrow(buf: &mut &'de [u8], version: i16) -> Result<Self, ProtocolError> {
721 let flex = version >= 9;
722 let mut out = Self::default();
723 if version >= 0 {
724 out.error_code = get_i16(buf)?;
725 }
726 if version >= 0 {
727 out.partition_index = get_i32(buf)?;
728 }
729 if version >= 0 {
730 out.leader_id = get_i32(buf)?;
731 }
732 if version >= 7 {
733 out.leader_epoch = get_i32(buf)?;
734 }
735 if version >= 0 {
736 out.replica_nodes = {
737 let n = get_array_len(buf, flex)?;
738 let mut v = Vec::with_capacity(n);
739 for _ in 0..n {
740 v.push(get_i32(buf)?);
741 }
742 v
743 };
744 }
745 if version >= 0 {
746 out.isr_nodes = {
747 let n = get_array_len(buf, flex)?;
748 let mut v = Vec::with_capacity(n);
749 for _ in 0..n {
750 v.push(get_i32(buf)?);
751 }
752 v
753 };
754 }
755 if version >= 5 {
756 out.offline_replicas = {
757 let n = get_array_len(buf, flex)?;
758 let mut v = Vec::with_capacity(n);
759 for _ in 0..n {
760 v.push(get_i32(buf)?);
761 }
762 v
763 };
764 }
765 if flex {
766 out.unknown_tagged_fields = read_tagged_fields(buf, |_tag, _payload| Ok(false))?;
767 }
768 Ok(out)
769 }
770}
771#[cfg(test)]
772impl MetadataResponsePartition {
773 #[must_use]
774 pub fn populated(version: i16) -> Self {
775 let mut m = Self::default();
776 if version >= 0 {
777 m.error_code = 1i16;
778 }
779 if version >= 0 {
780 m.partition_index = 1i32;
781 }
782 if version >= 0 {
783 m.leader_id = 1i32;
784 }
785 if version >= 7 {
786 m.leader_epoch = 1i32;
787 }
788 if version >= 0 {
789 m.replica_nodes = vec![1i32];
790 }
791 if version >= 0 {
792 m.isr_nodes = vec![1i32];
793 }
794 if version >= 5 {
795 m.offline_replicas = vec![1i32];
796 }
797 m
798 }
799}