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