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