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