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