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