1use bytes::{Buf, BufMut};
4
5use crate::{
6 Decode, Encode, ProtocolError, UnknownTaggedFields,
7 primitives::{
8 fixed::{get_i8, get_i32, get_i64, put_i8, put_i32, put_i64},
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, encode_to_bytes, read_tagged_fields, tagged_fields_len},
17};
18pub const API_KEY: i16 = 1;
19pub const MIN_VERSION: i16 = 4;
20pub const MAX_VERSION: i16 = 18;
21pub const LATEST_STABLE_VERSION: i16 = 18;
22pub const FLEXIBLE_MIN: i16 = 12;
23#[inline]
24#[must_use]
25pub fn is_flexible(version: i16) -> bool {
26 version >= FLEXIBLE_MIN
27}
28#[derive(Debug, Clone, PartialEq, Eq)]
29pub struct FetchRequest {
30 pub replica_id: i32,
31 pub max_wait_ms: i32,
32 pub min_bytes: i32,
33 pub max_bytes: i32,
34 pub isolation_level: i8,
35 pub session_id: i32,
36 pub session_epoch: i32,
37 pub topics: Vec<FetchTopic>,
38 pub forgotten_topics_data: Vec<ForgottenTopic>,
39 pub rack_id: String,
40 pub cluster_id: Option<String>,
41 pub replica_state: ReplicaState,
42 pub unknown_tagged_fields: UnknownTaggedFields,
43}
44impl Default for FetchRequest {
45 fn default() -> Self {
46 Self {
47 replica_id: -1i32,
48 max_wait_ms: 0i32,
49 min_bytes: 0i32,
50 max_bytes: 2_147_483_647i32,
51 isolation_level: 0i8,
52 session_id: 0i32,
53 session_epoch: -1i32,
54 topics: Vec::new(),
55 forgotten_topics_data: Vec::new(),
56 rack_id: String::new(),
57 cluster_id: None,
58 replica_state: ReplicaState::default(),
59 unknown_tagged_fields: UnknownTaggedFields::default(),
60 }
61 }
62}
63impl FetchRequest {
64 fn encode_field_0<B: BufMut>(&self, buf: &mut B, version: i16, _flex: bool) {
65 if (0..=14).contains(&version) {
66 put_i32(buf, self.replica_id);
67 }
68 }
69 fn encode_field_1<B: BufMut>(&self, buf: &mut B, version: i16, _flex: bool) {
70 if version >= 0 {
71 put_i32(buf, self.max_wait_ms);
72 }
73 }
74 fn encode_field_2<B: BufMut>(&self, buf: &mut B, version: i16, _flex: bool) {
75 if version >= 0 {
76 put_i32(buf, self.min_bytes);
77 }
78 }
79 fn encode_field_3<B: BufMut>(&self, buf: &mut B, version: i16, _flex: bool) {
80 if version >= 3 {
81 put_i32(buf, self.max_bytes);
82 }
83 }
84 fn encode_field_4<B: BufMut>(&self, buf: &mut B, version: i16, _flex: bool) {
85 if version >= 4 {
86 put_i8(buf, self.isolation_level);
87 }
88 }
89 fn encode_field_5<B: BufMut>(&self, buf: &mut B, version: i16, _flex: bool) {
90 if version >= 7 {
91 put_i32(buf, self.session_id);
92 }
93 }
94 fn encode_field_6<B: BufMut>(&self, buf: &mut B, version: i16, _flex: bool) {
95 if version >= 7 {
96 put_i32(buf, self.session_epoch);
97 }
98 }
99 fn encode_field_7<B: BufMut>(
100 &self,
101 buf: &mut B,
102 version: i16,
103 flex: bool,
104 ) -> Result<(), ProtocolError> {
105 if version >= 0 {
106 {
107 crate::primitives::array::put_array_len(buf, (self.topics).len(), flex);
108 for it in &self.topics {
109 it.encode(buf, version)?;
110 }
111 };
112 }
113 Ok(())
114 }
115 fn encode_field_8<B: BufMut>(
116 &self,
117 buf: &mut B,
118 version: i16,
119 flex: bool,
120 ) -> Result<(), ProtocolError> {
121 if version >= 7 {
122 {
123 crate::primitives::array::put_array_len(
124 buf,
125 (self.forgotten_topics_data).len(),
126 flex,
127 );
128 for it in &self.forgotten_topics_data {
129 it.encode(buf, version)?;
130 }
131 };
132 }
133 Ok(())
134 }
135 fn encode_field_9<B: BufMut>(&self, buf: &mut B, version: i16, flex: bool) {
136 if version >= 11 {
137 if flex {
138 let () = put_compact_string(buf, &self.rack_id);
139 } else {
140 let () = put_string(buf, &self.rack_id);
141 }
142 }
143 }
144 fn encode_tagged_fields<B: BufMut>(&self, buf: &mut B, version: i16, flex: bool) {
145 if flex {
146 let mut tagged = WriteTaggedFields::new();
147 if self.cluster_id.is_some() {
148 let payload = encode_to_bytes(
149 if flex {
150 compact_nullable_string_len(self.cluster_id.as_deref())
151 } else {
152 nullable_string_len(self.cluster_id.as_deref())
153 },
154 |b| {
155 if flex {
156 let () = put_compact_nullable_string(b, self.cluster_id.as_deref());
157 } else {
158 let () = put_nullable_string(b, self.cluster_id.as_deref());
159 }
160 Ok(())
161 },
162 );
163 tagged.add(0, payload);
164 }
165 if version >= 15 && !(crate::codegen_helpers::is_default(&self.replica_state)) {
166 let payload = encode_to_bytes(self.replica_state.encoded_len(version), |b| {
167 self.replica_state.encode(b, version)?;
168 Ok(())
169 });
170 tagged.add(1, payload);
171 }
172 tagged.write(buf, &self.unknown_tagged_fields);
173 }
174 }
175 fn decode_field_0<B: Buf>(
176 out: &mut Self,
177 buf: &mut B,
178 version: i16,
179 _flex: bool,
180 ) -> Result<(), ProtocolError> {
181 if (0..=14).contains(&version) {
182 out.replica_id = get_i32(buf)?;
183 }
184 Ok(())
185 }
186 fn decode_field_1<B: Buf>(
187 out: &mut Self,
188 buf: &mut B,
189 version: i16,
190 _flex: bool,
191 ) -> Result<(), ProtocolError> {
192 if version >= 0 {
193 out.max_wait_ms = get_i32(buf)?;
194 }
195 Ok(())
196 }
197 fn decode_field_2<B: Buf>(
198 out: &mut Self,
199 buf: &mut B,
200 version: i16,
201 _flex: bool,
202 ) -> Result<(), ProtocolError> {
203 if version >= 0 {
204 out.min_bytes = get_i32(buf)?;
205 }
206 Ok(())
207 }
208 fn decode_field_3<B: Buf>(
209 out: &mut Self,
210 buf: &mut B,
211 version: i16,
212 _flex: bool,
213 ) -> Result<(), ProtocolError> {
214 if version >= 3 {
215 out.max_bytes = get_i32(buf)?;
216 }
217 Ok(())
218 }
219 fn decode_field_4<B: Buf>(
220 out: &mut Self,
221 buf: &mut B,
222 version: i16,
223 _flex: bool,
224 ) -> Result<(), ProtocolError> {
225 if version >= 4 {
226 out.isolation_level = get_i8(buf)?;
227 }
228 Ok(())
229 }
230 fn decode_field_5<B: Buf>(
231 out: &mut Self,
232 buf: &mut B,
233 version: i16,
234 _flex: bool,
235 ) -> Result<(), ProtocolError> {
236 if version >= 7 {
237 out.session_id = get_i32(buf)?;
238 }
239 Ok(())
240 }
241 fn decode_field_6<B: Buf>(
242 out: &mut Self,
243 buf: &mut B,
244 version: i16,
245 _flex: bool,
246 ) -> Result<(), ProtocolError> {
247 if version >= 7 {
248 out.session_epoch = get_i32(buf)?;
249 }
250 Ok(())
251 }
252 fn decode_field_7<B: Buf>(
253 out: &mut Self,
254 buf: &mut B,
255 version: i16,
256 flex: bool,
257 ) -> Result<(), ProtocolError> {
258 if version >= 0 {
259 out.topics = {
260 let n = crate::primitives::array::get_array_len(buf, flex)?;
261 let mut v = Vec::with_capacity(n);
262 for _ in 0..n {
263 v.push(FetchTopic::decode(buf, version)?);
264 }
265 v
266 };
267 }
268 Ok(())
269 }
270 fn decode_field_8<B: Buf>(
271 out: &mut Self,
272 buf: &mut B,
273 version: i16,
274 flex: bool,
275 ) -> Result<(), ProtocolError> {
276 if version >= 7 {
277 out.forgotten_topics_data = {
278 let n = crate::primitives::array::get_array_len(buf, flex)?;
279 let mut v = Vec::with_capacity(n);
280 for _ in 0..n {
281 v.push(ForgottenTopic::decode(buf, version)?);
282 }
283 v
284 };
285 }
286 Ok(())
287 }
288 fn decode_field_9<B: Buf>(
289 out: &mut Self,
290 buf: &mut B,
291 version: i16,
292 flex: bool,
293 ) -> Result<(), ProtocolError> {
294 if version >= 11 {
295 out.rack_id = if flex {
296 get_compact_string_owned(buf)?
297 } else {
298 get_string_owned(buf)?
299 };
300 }
301 Ok(())
302 }
303 fn decode_tagged_fields<B: Buf>(
304 out: &mut Self,
305 buf: &mut B,
306 version: i16,
307 flex: bool,
308 ) -> Result<(), ProtocolError> {
309 if flex {
310 let mut tag_cluster_id = None;
311 let mut tag_replica_state = None;
312 out.unknown_tagged_fields = read_tagged_fields(buf, |tag, payload| match tag {
313 0 => {
314 tag_cluster_id = Some({
315 let b: &mut &[u8] = payload;
316 if flex {
317 get_compact_nullable_string_owned(b)?
318 } else {
319 get_nullable_string_owned(b)?
320 }
321 });
322 Ok(true)
323 }
324 1 if version >= 15 => {
325 tag_replica_state = Some({
326 let b: &mut &[u8] = payload;
327 ReplicaState::decode(b, version)?
328 });
329 Ok(true)
330 }
331 1 => Err(ProtocolError::TagNotValidForVersion { tag: 1, version }),
332 _ => Ok(false),
333 })?;
334 if let Some(v) = tag_cluster_id {
335 out.cluster_id = v;
336 }
337 if let Some(v) = tag_replica_state {
338 out.replica_state = v;
339 }
340 }
341 Ok(())
342 }
343}
344impl Encode for FetchRequest {
345 fn encode<B: BufMut>(&self, buf: &mut B, version: i16) -> Result<(), ProtocolError> {
346 if !(MIN_VERSION..=MAX_VERSION).contains(&version) {
347 return Err(ProtocolError::UnsupportedVersion {
348 api_key: API_KEY,
349 version,
350 });
351 }
352 let flex = is_flexible(version);
353 self.encode_field_0(buf, version, flex);
354 self.encode_field_1(buf, version, flex);
355 self.encode_field_2(buf, version, flex);
356 self.encode_field_3(buf, version, flex);
357 self.encode_field_4(buf, version, flex);
358 self.encode_field_5(buf, version, flex);
359 self.encode_field_6(buf, version, flex);
360 self.encode_field_7(buf, version, flex)?;
361 self.encode_field_8(buf, version, flex)?;
362 self.encode_field_9(buf, version, flex);
363 self.encode_tagged_fields(buf, version, flex);
364 Ok(())
365 }
366 fn encoded_len(&self, version: i16) -> usize {
367 let flex = is_flexible(version);
368 let mut n: usize = 0;
369 if (0..=14).contains(&version) {
370 n += 4;
371 }
372 if version >= 0 {
373 n += 4;
374 }
375 if version >= 0 {
376 n += 4;
377 }
378 if version >= 3 {
379 n += 4;
380 }
381 if version >= 4 {
382 n += 1;
383 }
384 if version >= 7 {
385 n += 4;
386 }
387 if version >= 7 {
388 n += 4;
389 }
390 if version >= 0 {
391 n += {
392 let prefix =
393 crate::primitives::array::array_len_prefix_len((self.topics).len(), flex);
394 let body: usize = (self.topics).iter().map(|it| it.encoded_len(version)).sum();
395 prefix + body
396 };
397 }
398 if version >= 7 {
399 n += {
400 let prefix = crate::primitives::array::array_len_prefix_len(
401 (self.forgotten_topics_data).len(),
402 flex,
403 );
404 let body: usize = (self.forgotten_topics_data)
405 .iter()
406 .map(|it| it.encoded_len(version))
407 .sum();
408 prefix + body
409 };
410 }
411 if version >= 11 {
412 n += if flex {
413 compact_string_len(&self.rack_id)
414 } else {
415 string_len(&self.rack_id)
416 };
417 }
418 if flex {
419 let mut known_pairs: Vec<(u32, usize)> = Vec::new();
420 if self.cluster_id.is_some() {
421 known_pairs.push((
422 0,
423 if flex {
424 compact_nullable_string_len(self.cluster_id.as_deref())
425 } else {
426 nullable_string_len(self.cluster_id.as_deref())
427 },
428 ));
429 }
430 if version >= 15 && !(crate::codegen_helpers::is_default(&self.replica_state)) {
431 known_pairs.push((1, self.replica_state.encoded_len(version)));
432 }
433 n += tagged_fields_len(&known_pairs, &self.unknown_tagged_fields);
434 }
435 n
436 }
437}
438impl Decode<'_> for FetchRequest {
439 fn decode<B: Buf>(buf: &mut B, version: i16) -> Result<Self, ProtocolError> {
440 if !(MIN_VERSION..=MAX_VERSION).contains(&version) {
441 return Err(ProtocolError::UnsupportedVersion {
442 api_key: API_KEY,
443 version,
444 });
445 }
446 let flex = is_flexible(version);
447 let mut out = Self::default();
448 Self::decode_field_0(&mut out, buf, version, flex)?;
449 Self::decode_field_1(&mut out, buf, version, flex)?;
450 Self::decode_field_2(&mut out, buf, version, flex)?;
451 Self::decode_field_3(&mut out, buf, version, flex)?;
452 Self::decode_field_4(&mut out, buf, version, flex)?;
453 Self::decode_field_5(&mut out, buf, version, flex)?;
454 Self::decode_field_6(&mut out, buf, version, flex)?;
455 Self::decode_field_7(&mut out, buf, version, flex)?;
456 Self::decode_field_8(&mut out, buf, version, flex)?;
457 Self::decode_field_9(&mut out, buf, version, flex)?;
458 Self::decode_tagged_fields(&mut out, buf, version, flex)?;
459 Ok(out)
460 }
461}
462#[cfg(test)]
463impl FetchRequest {
464 #[must_use]
465 pub fn populated(version: i16) -> Self {
466 let mut m = Self::default();
467 if (0..=14).contains(&version) {
468 m.replica_id = 1i32;
469 }
470 if version >= 0 {
471 m.max_wait_ms = 1i32;
472 }
473 if version >= 0 {
474 m.min_bytes = 1i32;
475 }
476 if version >= 3 {
477 m.max_bytes = 1i32;
478 }
479 if version >= 4 {
480 m.isolation_level = 1i8;
481 }
482 if version >= 7 {
483 m.session_id = 1i32;
484 }
485 if version >= 7 {
486 m.session_epoch = 1i32;
487 }
488 if version >= 0 {
489 m.topics = vec![FetchTopic::populated(version)];
490 }
491 if version >= 7 {
492 m.forgotten_topics_data = vec![ForgottenTopic::populated(version)];
493 }
494 if version >= 11 {
495 m.rack_id = "x".to_string();
496 }
497 if version >= 12 {
498 m.cluster_id = Some("x".to_string());
499 }
500 if version >= 15 {
501 m.replica_state = ReplicaState::populated(version);
502 }
503 m
504 }
505}
506#[derive(Debug, Clone, PartialEq, Eq)]
507pub struct ReplicaState {
508 pub replica_id: i32,
509 pub replica_epoch: i64,
510 pub unknown_tagged_fields: UnknownTaggedFields,
511}
512impl Default for ReplicaState {
513 fn default() -> Self {
514 Self {
515 replica_id: -1i32,
516 replica_epoch: -1i64,
517 unknown_tagged_fields: UnknownTaggedFields::default(),
518 }
519 }
520}
521impl Encode for ReplicaState {
522 fn encode<B: BufMut>(&self, buf: &mut B, version: i16) -> Result<(), ProtocolError> {
523 let flex = version >= 12;
524 if version >= 15 {
525 put_i32(buf, self.replica_id);
526 }
527 if version >= 15 {
528 put_i64(buf, self.replica_epoch);
529 }
530 if flex {
531 let tagged = WriteTaggedFields::new();
532 tagged.write(buf, &self.unknown_tagged_fields);
533 }
534 Ok(())
535 }
536 fn encoded_len(&self, version: i16) -> usize {
537 let flex = version >= 12;
538 let mut n: usize = 0;
539 if version >= 15 {
540 n += 4;
541 }
542 if version >= 15 {
543 n += 8;
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 ReplicaState {
553 fn decode<B: Buf>(buf: &mut B, version: i16) -> Result<Self, ProtocolError> {
554 let flex = version >= 12;
555 let mut out = Self::default();
556 if version >= 15 {
557 out.replica_id = get_i32(buf)?;
558 }
559 if version >= 15 {
560 out.replica_epoch = get_i64(buf)?;
561 }
562 if flex {
563 out.unknown_tagged_fields = read_tagged_fields(buf, |_tag, _payload| Ok(false))?;
564 }
565 Ok(out)
566 }
567}
568#[cfg(test)]
569impl ReplicaState {
570 #[must_use]
571 pub fn populated(version: i16) -> Self {
572 let mut m = Self::default();
573 if version >= 15 {
574 m.replica_id = 1i32;
575 }
576 if version >= 15 {
577 m.replica_epoch = 1i64;
578 }
579 m
580 }
581}
582#[derive(Debug, Clone, PartialEq, Eq, Default)]
583pub struct FetchTopic {
584 pub topic: String,
585 pub topic_id: crate::primitives::uuid::Uuid,
586 pub partitions: Vec<FetchPartition>,
587 pub unknown_tagged_fields: UnknownTaggedFields,
588}
589impl Encode for FetchTopic {
590 fn encode<B: BufMut>(&self, buf: &mut B, version: i16) -> Result<(), ProtocolError> {
591 let flex = version >= 12;
592 if (0..=12).contains(&version) {
593 if flex {
594 let () = put_compact_string(buf, &self.topic);
595 } else {
596 let () = put_string(buf, &self.topic);
597 }
598 }
599 if version >= 13 {
600 crate::primitives::uuid::put_uuid(buf, self.topic_id);
601 }
602 if version >= 0 {
603 {
604 crate::primitives::array::put_array_len(buf, (self.partitions).len(), flex);
605 for it in &self.partitions {
606 it.encode(buf, version)?;
607 }
608 };
609 }
610 if flex {
611 let tagged = WriteTaggedFields::new();
612 tagged.write(buf, &self.unknown_tagged_fields);
613 }
614 Ok(())
615 }
616 fn encoded_len(&self, version: i16) -> usize {
617 let flex = version >= 12;
618 let mut n: usize = 0;
619 if (0..=12).contains(&version) {
620 n += if flex {
621 compact_string_len(&self.topic)
622 } else {
623 string_len(&self.topic)
624 };
625 }
626 if version >= 13 {
627 n += 16;
628 }
629 if version >= 0 {
630 n += {
631 let prefix =
632 crate::primitives::array::array_len_prefix_len((self.partitions).len(), flex);
633 let body: usize = (self.partitions)
634 .iter()
635 .map(|it| it.encoded_len(version))
636 .sum();
637 prefix + body
638 };
639 }
640 if flex {
641 let known_pairs: Vec<(u32, usize)> = Vec::new();
642 n += tagged_fields_len(&known_pairs, &self.unknown_tagged_fields);
643 }
644 n
645 }
646}
647impl Decode<'_> for FetchTopic {
648 fn decode<B: Buf>(buf: &mut B, version: i16) -> Result<Self, ProtocolError> {
649 let flex = version >= 12;
650 let mut out = Self::default();
651 if (0..=12).contains(&version) {
652 out.topic = if flex {
653 get_compact_string_owned(buf)?
654 } else {
655 get_string_owned(buf)?
656 };
657 }
658 if version >= 13 {
659 out.topic_id = crate::primitives::uuid::get_uuid(buf)?;
660 }
661 if version >= 0 {
662 out.partitions = {
663 let n = crate::primitives::array::get_array_len(buf, flex)?;
664 let mut v = Vec::with_capacity(n);
665 for _ in 0..n {
666 v.push(FetchPartition::decode(buf, version)?);
667 }
668 v
669 };
670 }
671 if flex {
672 out.unknown_tagged_fields = read_tagged_fields(buf, |_tag, _payload| Ok(false))?;
673 }
674 Ok(out)
675 }
676}
677#[cfg(test)]
678impl FetchTopic {
679 #[must_use]
680 pub fn populated(version: i16) -> Self {
681 let mut m = Self::default();
682 if (0..=12).contains(&version) {
683 m.topic = "x".to_string();
684 }
685 if version >= 13 {
686 m.topic_id = crate::primitives::uuid::Uuid([1u8; 16]);
687 }
688 if version >= 0 {
689 m.partitions = vec![FetchPartition::populated(version)];
690 }
691 m
692 }
693}
694#[derive(Debug, Clone, PartialEq, Eq)]
695pub struct FetchPartition {
696 pub partition: i32,
697 pub current_leader_epoch: i32,
698 pub fetch_offset: i64,
699 pub last_fetched_epoch: i32,
700 pub log_start_offset: i64,
701 pub partition_max_bytes: i32,
702 pub replica_directory_id: crate::primitives::uuid::Uuid,
703 pub high_watermark: i64,
704 pub unknown_tagged_fields: UnknownTaggedFields,
705}
706impl Default for FetchPartition {
707 fn default() -> Self {
708 Self {
709 partition: 0i32,
710 current_leader_epoch: -1i32,
711 fetch_offset: 0i64,
712 last_fetched_epoch: -1i32,
713 log_start_offset: -1i64,
714 partition_max_bytes: 0i32,
715 replica_directory_id: crate::primitives::uuid::Uuid::default(),
716 high_watermark: 9_223_372_036_854_775_807i64,
717 unknown_tagged_fields: UnknownTaggedFields::default(),
718 }
719 }
720}
721impl FetchPartition {
722 fn encode_field_0<B: BufMut>(&self, buf: &mut B, version: i16, _flex: bool) {
723 if version >= 0 {
724 put_i32(buf, self.partition);
725 }
726 }
727 fn encode_field_1<B: BufMut>(&self, buf: &mut B, version: i16, _flex: bool) {
728 if version >= 9 {
729 put_i32(buf, self.current_leader_epoch);
730 }
731 }
732 fn encode_field_2<B: BufMut>(&self, buf: &mut B, version: i16, _flex: bool) {
733 if version >= 0 {
734 put_i64(buf, self.fetch_offset);
735 }
736 }
737 fn encode_field_3<B: BufMut>(&self, buf: &mut B, version: i16, _flex: bool) {
738 if version >= 12 {
739 put_i32(buf, self.last_fetched_epoch);
740 }
741 }
742 fn encode_field_4<B: BufMut>(&self, buf: &mut B, version: i16, _flex: bool) {
743 if version >= 5 {
744 put_i64(buf, self.log_start_offset);
745 }
746 }
747 fn encode_field_5<B: BufMut>(&self, buf: &mut B, version: i16, _flex: bool) {
748 if version >= 0 {
749 put_i32(buf, self.partition_max_bytes);
750 }
751 }
752 fn encode_tagged_fields<B: BufMut>(&self, buf: &mut B, version: i16, flex: bool) {
753 if flex {
754 let mut tagged = WriteTaggedFields::new();
755 if version >= 17 && !(crate::codegen_helpers::is_default(&self.replica_directory_id)) {
756 let payload = encode_to_bytes(16, |b| {
757 crate::primitives::uuid::put_uuid(b, self.replica_directory_id);
758 Ok(())
759 });
760 tagged.add(0, payload);
761 }
762 if version >= 18 && self.high_watermark != 9_223_372_036_854_775_807i64 {
763 let payload = encode_to_bytes(8, |b| {
764 put_i64(b, self.high_watermark);
765 Ok(())
766 });
767 tagged.add(1, payload);
768 }
769 tagged.write(buf, &self.unknown_tagged_fields);
770 }
771 }
772 fn decode_field_0<B: Buf>(
773 out: &mut Self,
774 buf: &mut B,
775 version: i16,
776 _flex: bool,
777 ) -> Result<(), ProtocolError> {
778 if version >= 0 {
779 out.partition = get_i32(buf)?;
780 }
781 Ok(())
782 }
783 fn decode_field_1<B: Buf>(
784 out: &mut Self,
785 buf: &mut B,
786 version: i16,
787 _flex: bool,
788 ) -> Result<(), ProtocolError> {
789 if version >= 9 {
790 out.current_leader_epoch = get_i32(buf)?;
791 }
792 Ok(())
793 }
794 fn decode_field_2<B: Buf>(
795 out: &mut Self,
796 buf: &mut B,
797 version: i16,
798 _flex: bool,
799 ) -> Result<(), ProtocolError> {
800 if version >= 0 {
801 out.fetch_offset = get_i64(buf)?;
802 }
803 Ok(())
804 }
805 fn decode_field_3<B: Buf>(
806 out: &mut Self,
807 buf: &mut B,
808 version: i16,
809 _flex: bool,
810 ) -> Result<(), ProtocolError> {
811 if version >= 12 {
812 out.last_fetched_epoch = get_i32(buf)?;
813 }
814 Ok(())
815 }
816 fn decode_field_4<B: Buf>(
817 out: &mut Self,
818 buf: &mut B,
819 version: i16,
820 _flex: bool,
821 ) -> Result<(), ProtocolError> {
822 if version >= 5 {
823 out.log_start_offset = get_i64(buf)?;
824 }
825 Ok(())
826 }
827 fn decode_field_5<B: Buf>(
828 out: &mut Self,
829 buf: &mut B,
830 version: i16,
831 _flex: bool,
832 ) -> Result<(), ProtocolError> {
833 if version >= 0 {
834 out.partition_max_bytes = get_i32(buf)?;
835 }
836 Ok(())
837 }
838 fn decode_tagged_fields<B: Buf>(
839 out: &mut Self,
840 buf: &mut B,
841 version: i16,
842 flex: bool,
843 ) -> Result<(), ProtocolError> {
844 if flex {
845 let mut tag_replica_directory_id = None;
846 let mut tag_high_watermark = None;
847 out.unknown_tagged_fields = read_tagged_fields(buf, |tag, payload| match tag {
848 0 if version >= 17 => {
849 tag_replica_directory_id = Some({
850 let b: &mut &[u8] = payload;
851 crate::primitives::uuid::get_uuid(b)?
852 });
853 Ok(true)
854 }
855 0 => Err(ProtocolError::TagNotValidForVersion { tag: 0, version }),
856 1 if version >= 18 => {
857 tag_high_watermark = Some({
858 let b: &mut &[u8] = payload;
859 get_i64(b)?
860 });
861 Ok(true)
862 }
863 1 => Err(ProtocolError::TagNotValidForVersion { tag: 1, version }),
864 _ => Ok(false),
865 })?;
866 if let Some(v) = tag_replica_directory_id {
867 out.replica_directory_id = v;
868 }
869 if let Some(v) = tag_high_watermark {
870 out.high_watermark = v;
871 }
872 }
873 Ok(())
874 }
875}
876impl Encode for FetchPartition {
877 fn encode<B: BufMut>(&self, buf: &mut B, version: i16) -> Result<(), ProtocolError> {
878 let flex = version >= 12;
879 self.encode_field_0(buf, version, flex);
880 self.encode_field_1(buf, version, flex);
881 self.encode_field_2(buf, version, flex);
882 self.encode_field_3(buf, version, flex);
883 self.encode_field_4(buf, version, flex);
884 self.encode_field_5(buf, version, flex);
885 self.encode_tagged_fields(buf, version, flex);
886 Ok(())
887 }
888 fn encoded_len(&self, version: i16) -> usize {
889 let flex = version >= 12;
890 let mut n: usize = 0;
891 if version >= 0 {
892 n += 4;
893 }
894 if version >= 9 {
895 n += 4;
896 }
897 if version >= 0 {
898 n += 8;
899 }
900 if version >= 12 {
901 n += 4;
902 }
903 if version >= 5 {
904 n += 8;
905 }
906 if version >= 0 {
907 n += 4;
908 }
909 if flex {
910 let mut known_pairs: Vec<(u32, usize)> = Vec::new();
911 if version >= 17 && !(crate::codegen_helpers::is_default(&self.replica_directory_id)) {
912 known_pairs.push((0, 16));
913 }
914 if version >= 18 && self.high_watermark != 9_223_372_036_854_775_807i64 {
915 known_pairs.push((1, 8));
916 }
917 n += tagged_fields_len(&known_pairs, &self.unknown_tagged_fields);
918 }
919 n
920 }
921}
922impl Decode<'_> for FetchPartition {
923 fn decode<B: Buf>(buf: &mut B, version: i16) -> Result<Self, ProtocolError> {
924 let flex = version >= 12;
925 let mut out = Self::default();
926 Self::decode_field_0(&mut out, buf, version, flex)?;
927 Self::decode_field_1(&mut out, buf, version, flex)?;
928 Self::decode_field_2(&mut out, buf, version, flex)?;
929 Self::decode_field_3(&mut out, buf, version, flex)?;
930 Self::decode_field_4(&mut out, buf, version, flex)?;
931 Self::decode_field_5(&mut out, buf, version, flex)?;
932 Self::decode_tagged_fields(&mut out, buf, version, flex)?;
933 Ok(out)
934 }
935}
936#[cfg(test)]
937impl FetchPartition {
938 #[must_use]
939 pub fn populated(version: i16) -> Self {
940 let mut m = Self::default();
941 if version >= 0 {
942 m.partition = 1i32;
943 }
944 if version >= 9 {
945 m.current_leader_epoch = 1i32;
946 }
947 if version >= 0 {
948 m.fetch_offset = 1i64;
949 }
950 if version >= 12 {
951 m.last_fetched_epoch = 1i32;
952 }
953 if version >= 5 {
954 m.log_start_offset = 1i64;
955 }
956 if version >= 0 {
957 m.partition_max_bytes = 1i32;
958 }
959 if version >= 17 {
960 m.replica_directory_id = crate::primitives::uuid::Uuid([1u8; 16]);
961 }
962 if version >= 18 {
963 m.high_watermark = 1i64;
964 }
965 m
966 }
967}
968#[derive(Debug, Clone, PartialEq, Eq, Default)]
969pub struct ForgottenTopic {
970 pub topic: String,
971 pub topic_id: crate::primitives::uuid::Uuid,
972 pub partitions: Vec<i32>,
973 pub unknown_tagged_fields: UnknownTaggedFields,
974}
975impl Encode for ForgottenTopic {
976 fn encode<B: BufMut>(&self, buf: &mut B, version: i16) -> Result<(), ProtocolError> {
977 let flex = version >= 12;
978 if (7..=12).contains(&version) {
979 if flex {
980 let () = put_compact_string(buf, &self.topic);
981 } else {
982 let () = put_string(buf, &self.topic);
983 }
984 }
985 if version >= 13 {
986 crate::primitives::uuid::put_uuid(buf, self.topic_id);
987 }
988 if version >= 7 {
989 {
990 crate::primitives::array::put_array_len(buf, (self.partitions).len(), flex);
991 for it in &self.partitions {
992 put_i32(buf, *it);
993 }
994 };
995 }
996 if flex {
997 let tagged = WriteTaggedFields::new();
998 tagged.write(buf, &self.unknown_tagged_fields);
999 }
1000 Ok(())
1001 }
1002 fn encoded_len(&self, version: i16) -> usize {
1003 let flex = version >= 12;
1004 let mut n: usize = 0;
1005 if (7..=12).contains(&version) {
1006 n += if flex {
1007 compact_string_len(&self.topic)
1008 } else {
1009 string_len(&self.topic)
1010 };
1011 }
1012 if version >= 13 {
1013 n += 16;
1014 }
1015 if version >= 7 {
1016 n += {
1017 let prefix =
1018 crate::primitives::array::array_len_prefix_len((self.partitions).len(), flex);
1019 let body: usize = (self.partitions).iter().map(|_| 4).sum();
1020 prefix + body
1021 };
1022 }
1023 if flex {
1024 let known_pairs: Vec<(u32, usize)> = Vec::new();
1025 n += tagged_fields_len(&known_pairs, &self.unknown_tagged_fields);
1026 }
1027 n
1028 }
1029}
1030impl Decode<'_> for ForgottenTopic {
1031 fn decode<B: Buf>(buf: &mut B, version: i16) -> Result<Self, ProtocolError> {
1032 let flex = version >= 12;
1033 let mut out = Self::default();
1034 if (7..=12).contains(&version) {
1035 out.topic = if flex {
1036 get_compact_string_owned(buf)?
1037 } else {
1038 get_string_owned(buf)?
1039 };
1040 }
1041 if version >= 13 {
1042 out.topic_id = crate::primitives::uuid::get_uuid(buf)?;
1043 }
1044 if version >= 7 {
1045 out.partitions = {
1046 let n = crate::primitives::array::get_array_len(buf, flex)?;
1047 let mut v = Vec::with_capacity(n);
1048 for _ in 0..n {
1049 v.push(get_i32(buf)?);
1050 }
1051 v
1052 };
1053 }
1054 if flex {
1055 out.unknown_tagged_fields = read_tagged_fields(buf, |_tag, _payload| Ok(false))?;
1056 }
1057 Ok(out)
1058 }
1059}
1060#[cfg(test)]
1061impl ForgottenTopic {
1062 #[must_use]
1063 pub fn populated(version: i16) -> Self {
1064 let mut m = Self::default();
1065 if (7..=12).contains(&version) {
1066 m.topic = "x".to_string();
1067 }
1068 if version >= 13 {
1069 m.topic_id = crate::primitives::uuid::Uuid([1u8; 16]);
1070 }
1071 if version >= 7 {
1072 m.partitions = vec![1i32];
1073 }
1074 m
1075 }
1076}
1077#[must_use]
1080#[allow(unused_comparisons)]
1081pub fn default_json(version: i16) -> ::serde_json::Value {
1082 let mut obj = ::serde_json::Map::new();
1083 if version >= 12 {
1084 obj.insert("clusterId".to_string(), ::serde_json::Value::Null);
1085 }
1086 if version <= 14 {
1087 obj.insert("replicaId".to_string(), ::serde_json::json!(-1));
1088 }
1089 if version >= 15 {
1090 obj.insert("replicaState".to_string(), {
1091 let mut m = ::serde_json::Map::new();
1092 m.insert("replicaId".to_string(), ::serde_json::json!(-1));
1093 m.insert("replicaEpoch".to_string(), ::serde_json::json!(-1));
1094 ::serde_json::Value::Object(m)
1095 });
1096 }
1097 obj.insert("maxWaitMs".to_string(), ::serde_json::json!(0));
1098 obj.insert("minBytes".to_string(), ::serde_json::json!(0));
1099 if version >= 3 {
1100 obj.insert("maxBytes".to_string(), ::serde_json::json!(2_147_483_647));
1101 }
1102 if version >= 4 {
1103 obj.insert("isolationLevel".to_string(), ::serde_json::json!(0));
1104 }
1105 if version >= 7 {
1106 obj.insert("sessionId".to_string(), ::serde_json::json!(0));
1107 }
1108 if version >= 7 {
1109 obj.insert("sessionEpoch".to_string(), ::serde_json::json!(-1));
1110 }
1111 obj.insert("topics".to_string(), ::serde_json::Value::Array(vec![]));
1112 if version >= 7 {
1113 obj.insert(
1114 "forgottenTopicsData".to_string(),
1115 ::serde_json::Value::Array(vec![]),
1116 );
1117 }
1118 if version >= 11 {
1119 obj.insert(
1120 "rackId".to_string(),
1121 ::serde_json::Value::String(String::new()),
1122 );
1123 }
1124 ::serde_json::Value::Object(obj)
1125}
1126#[must_use]
1129pub fn tagged_fixture() -> FetchRequest {
1130 FetchRequest {
1131 cluster_id: Some("x".to_string()),
1132 replica_state: ReplicaState {
1133 replica_id: 1i32,
1134 replica_epoch: 1i64,
1135 ..ReplicaState::default()
1136 },
1137 topics: vec![FetchTopic {
1138 partitions: vec![FetchPartition {
1139 replica_directory_id: crate::primitives::uuid::Uuid([1u8; 16]),
1140 high_watermark: 1i64,
1141 ..FetchPartition::default()
1142 }],
1143 ..FetchTopic::default()
1144 }],
1145 ..FetchRequest::default()
1146 }
1147}
1148#[must_use]
1151pub fn tagged_fixture_json(version: i16) -> ::serde_json::Value {
1152 let mut m = ::serde_json::Map::new();
1153 if version >= 12 {
1154 m.insert(
1155 "clusterId".to_string(),
1156 ::serde_json::Value::String("x".to_string()),
1157 );
1158 }
1159 if version <= 14 {
1160 m.insert("replicaId".to_string(), ::serde_json::json!(-1));
1161 }
1162 if version >= 15 {
1163 m.insert("replicaState".to_string(), {
1164 let mut m = ::serde_json::Map::new();
1165 m.insert("replicaId".to_string(), ::serde_json::json!(1));
1166 m.insert("replicaEpoch".to_string(), ::serde_json::json!(1));
1167 ::serde_json::Value::Object(m)
1168 });
1169 }
1170 m.insert("maxWaitMs".to_string(), ::serde_json::json!(0));
1171 m.insert("minBytes".to_string(), ::serde_json::json!(0));
1172 m.insert("maxBytes".to_string(), ::serde_json::json!(2_147_483_647));
1173 m.insert("isolationLevel".to_string(), ::serde_json::json!(0));
1174 if version >= 7 {
1175 m.insert("sessionId".to_string(), ::serde_json::json!(0));
1176 }
1177 if version >= 7 {
1178 m.insert("sessionEpoch".to_string(), ::serde_json::json!(-1));
1179 }
1180 m.insert(
1181 "topics".to_string(),
1182 ::serde_json::Value::Array(vec![{
1183 let mut m = ::serde_json::Map::new();
1184 if version <= 12 {
1185 m.insert(
1186 "topic".to_string(),
1187 ::serde_json::Value::String(String::new()),
1188 );
1189 }
1190 if version >= 13 {
1191 m.insert(
1192 "topicId".to_string(),
1193 ::serde_json::Value::String("AAAAAAAAAAAAAAAAAAAAAA".to_string()),
1194 );
1195 }
1196 m.insert(
1197 "partitions".to_string(),
1198 ::serde_json::Value::Array(vec![{
1199 let mut m = ::serde_json::Map::new();
1200 m.insert("partition".to_string(), ::serde_json::json!(0));
1201 if version >= 9 {
1202 m.insert("currentLeaderEpoch".to_string(), ::serde_json::json!(-1));
1203 }
1204 m.insert("fetchOffset".to_string(), ::serde_json::json!(0));
1205 if version >= 12 {
1206 m.insert("lastFetchedEpoch".to_string(), ::serde_json::json!(-1));
1207 }
1208 if version >= 5 {
1209 m.insert("logStartOffset".to_string(), ::serde_json::json!(-1));
1210 }
1211 m.insert("partitionMaxBytes".to_string(), ::serde_json::json!(0));
1212 if version >= 17 {
1213 m.insert(
1214 "replicaDirectoryId".to_string(),
1215 ::serde_json::Value::String("AQEBAQEBAQEBAQEBAQEBAQ".to_string()),
1216 );
1217 }
1218 if version == 18 {
1219 m.insert("highWatermark".to_string(), ::serde_json::json!(1));
1220 }
1221 ::serde_json::Value::Object(m)
1222 }]),
1223 );
1224 ::serde_json::Value::Object(m)
1225 }]),
1226 );
1227 if version >= 7 {
1228 m.insert(
1229 "forgottenTopicsData".to_string(),
1230 ::serde_json::Value::Array(vec![]),
1231 );
1232 }
1233 if version >= 11 {
1234 m.insert(
1235 "rackId".to_string(),
1236 ::serde_json::Value::String(String::new()),
1237 );
1238 }
1239 ::serde_json::Value::Object(m)
1240}
1241impl crate::ProtocolRequest for FetchRequest {
1242 const API_KEY: i16 = API_KEY;
1243 const MIN_VERSION: i16 = MIN_VERSION;
1244 const MAX_VERSION: i16 = MAX_VERSION;
1245 const LATEST_STABLE_VERSION: i16 = LATEST_STABLE_VERSION;
1246 const FLEXIBLE_MIN: i16 = FLEXIBLE_MIN;
1247 type Response = super::fetch_response::FetchResponse;
1248}