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