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