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