krabka_protocol/krabka/barrier/
describe_barrier_groups.rs1use bytes::{Buf, BufMut};
7
8#[cfg(test)]
9use crate::krabka::test_support::sample_tagged_fields;
10use crate::{
11 Decode, Encode, ProtocolError, ProtocolRequest, UnknownTaggedFields,
12 krabka::common::{
13 I16_LEN, I32_LEN, I64_LEN, array_len, check_version, decode_array, decode_string_array,
14 encode_array, encode_string_array, read_unknown_tagged_fields, string_array_len,
15 unknown_tagged_fields_len, write_unknown_tagged_fields,
16 },
17 primitives::{
18 fixed::{get_i16, get_i32, get_i64, put_i16, put_i32, put_i64},
19 string_bytes::{
20 compact_nullable_string_len, compact_string_len, get_compact_nullable_string_owned,
21 get_compact_string_owned, put_compact_nullable_string, put_compact_string,
22 },
23 },
24};
25
26pub const API_KEY: i16 = 1011;
28pub const MIN_VERSION: i16 = 0;
30pub const MAX_VERSION: i16 = 0;
32pub const FLEXIBLE_MIN: i16 = 0;
34
35#[inline]
40#[must_use]
41pub fn is_flexible(version: i16) -> bool {
42 version >= FLEXIBLE_MIN
43}
44
45#[derive(Debug, Clone, PartialEq, Eq, Default)]
47pub struct DescribeBarrierGroupsRequest {
48 pub groups: Vec<String>,
50 pub unknown_tagged_fields: UnknownTaggedFields,
52}
53
54impl Encode for DescribeBarrierGroupsRequest {
55 fn encode<B: BufMut>(&self, buf: &mut B, version: i16) -> Result<(), ProtocolError> {
56 check_version(API_KEY, version, MIN_VERSION, MAX_VERSION)?;
57 encode_string_array(buf, &self.groups)?;
58 write_unknown_tagged_fields(buf, &self.unknown_tagged_fields)?;
59 Ok(())
60 }
61
62 fn encoded_len(&self, _version: i16) -> usize {
63 string_array_len(&self.groups) + unknown_tagged_fields_len(&self.unknown_tagged_fields)
64 }
65}
66
67impl Decode<'_> for DescribeBarrierGroupsRequest {
68 fn decode<B: Buf>(buf: &mut B, version: i16) -> Result<Self, ProtocolError> {
69 check_version(API_KEY, version, MIN_VERSION, MAX_VERSION)?;
70 Ok(Self {
71 groups: decode_string_array(buf)?,
72 unknown_tagged_fields: read_unknown_tagged_fields(buf)?,
73 })
74 }
75}
76
77impl ProtocolRequest for DescribeBarrierGroupsRequest {
78 const API_KEY: i16 = API_KEY;
79 const MIN_VERSION: i16 = MIN_VERSION;
80 const MAX_VERSION: i16 = MAX_VERSION;
81 const LATEST_STABLE_VERSION: i16 = MAX_VERSION;
82 const FLEXIBLE_MIN: i16 = FLEXIBLE_MIN;
83
84 type Response = DescribeBarrierGroupsResponse;
85}
86
87#[derive(Debug, Clone, PartialEq, Eq)]
89pub struct DescribedBarrierGroup {
90 pub group: String,
92 pub error_code: i16,
94 pub error_message: Option<String>,
97 pub topics: Vec<String>,
99 pub interval_ms: i64,
102 pub retained_cuts: i32,
104 pub last_epoch: i64,
107 pub coordinator_id: i32,
110 pub unknown_tagged_fields: UnknownTaggedFields,
112}
113
114impl Default for DescribedBarrierGroup {
115 fn default() -> Self {
116 Self {
117 group: String::new(),
118 error_code: 0,
119 error_message: None,
120 topics: Vec::new(),
121 interval_ms: -1,
122 retained_cuts: 0,
123 last_epoch: -1,
124 coordinator_id: -1,
125 unknown_tagged_fields: UnknownTaggedFields::default(),
126 }
127 }
128}
129
130impl Encode for DescribedBarrierGroup {
131 fn encode<B: BufMut>(&self, buf: &mut B, _version: i16) -> Result<(), ProtocolError> {
132 put_compact_string(buf, &self.group)?;
133 put_i16(buf, self.error_code);
134 put_compact_nullable_string(buf, self.error_message.as_deref())?;
135 encode_string_array(buf, &self.topics)?;
136 put_i64(buf, self.interval_ms);
137 put_i32(buf, self.retained_cuts);
138 put_i64(buf, self.last_epoch);
139 put_i32(buf, self.coordinator_id);
140 write_unknown_tagged_fields(buf, &self.unknown_tagged_fields)?;
141 Ok(())
142 }
143
144 fn encoded_len(&self, _version: i16) -> usize {
145 compact_string_len(&self.group)
146 + I16_LEN
147 + compact_nullable_string_len(self.error_message.as_deref())
148 + string_array_len(&self.topics)
149 + I64_LEN
150 + I32_LEN
151 + I64_LEN
152 + I32_LEN
153 + unknown_tagged_fields_len(&self.unknown_tagged_fields)
154 }
155}
156
157impl Decode<'_> for DescribedBarrierGroup {
158 fn decode<B: Buf>(buf: &mut B, _version: i16) -> Result<Self, ProtocolError> {
159 Ok(Self {
160 group: get_compact_string_owned(buf)?,
161 error_code: get_i16(buf)?,
162 error_message: get_compact_nullable_string_owned(buf)?,
163 topics: decode_string_array(buf)?,
164 interval_ms: get_i64(buf)?,
165 retained_cuts: get_i32(buf)?,
166 last_epoch: get_i64(buf)?,
167 coordinator_id: get_i32(buf)?,
168 unknown_tagged_fields: read_unknown_tagged_fields(buf)?,
169 })
170 }
171}
172
173#[derive(Debug, Clone, PartialEq, Eq, Default)]
175pub struct DescribeBarrierGroupsResponse {
176 pub throttle_time_ms: i32,
178 pub groups: Vec<DescribedBarrierGroup>,
181 pub unknown_tagged_fields: UnknownTaggedFields,
183}
184
185impl Encode for DescribeBarrierGroupsResponse {
186 fn encode<B: BufMut>(&self, buf: &mut B, version: i16) -> Result<(), ProtocolError> {
187 check_version(API_KEY, version, MIN_VERSION, MAX_VERSION)?;
188 put_i32(buf, self.throttle_time_ms);
189 encode_array(buf, &self.groups, version)?;
190 write_unknown_tagged_fields(buf, &self.unknown_tagged_fields)?;
191 Ok(())
192 }
193
194 fn encoded_len(&self, version: i16) -> usize {
195 I32_LEN
196 + array_len(&self.groups, version)
197 + unknown_tagged_fields_len(&self.unknown_tagged_fields)
198 }
199}
200
201impl Decode<'_> for DescribeBarrierGroupsResponse {
202 fn decode<B: Buf>(buf: &mut B, version: i16) -> Result<Self, ProtocolError> {
203 check_version(API_KEY, version, MIN_VERSION, MAX_VERSION)?;
204 Ok(Self {
205 throttle_time_ms: get_i32(buf)?,
206 groups: decode_array(buf, version)?,
207 unknown_tagged_fields: read_unknown_tagged_fields(buf)?,
208 })
209 }
210}
211
212#[cfg(test)]
213impl DescribeBarrierGroupsRequest {
214 fn populated() -> Self {
216 Self {
217 groups: vec!["orders".to_owned(), "audit".to_owned()],
218 unknown_tagged_fields: sample_tagged_fields(),
219 }
220 }
221}
222
223#[cfg(test)]
224impl DescribeBarrierGroupsResponse {
225 fn populated() -> Self {
227 Self {
228 throttle_time_ms: 5,
229 groups: vec![
230 DescribedBarrierGroup {
231 group: "orders".to_owned(),
232 error_code: 0,
233 error_message: None,
234 topics: vec!["orders".to_owned(), "payments".to_owned()],
235 interval_ms: 30_000,
236 retained_cuts: 64,
237 last_epoch: 12,
238 coordinator_id: 3,
239 unknown_tagged_fields: sample_tagged_fields(),
240 },
241 DescribedBarrierGroup {
242 group: "audit".to_owned(),
243 error_code: 69,
244 error_message: Some("barrier group not found".to_owned()),
245 ..DescribedBarrierGroup::default()
246 },
247 ],
248 unknown_tagged_fields: UnknownTaggedFields::default(),
249 }
250 }
251}
252
253#[cfg(test)]
254mod tests {
255 use assert2::assert;
256
257 use super::*;
258 use crate::krabka::test_support::{roundtrip, unsupported_versions};
259
260 #[test]
261 fn default_roundtrips_all_versions() {
262 for version in MIN_VERSION..=MAX_VERSION {
263 roundtrip(&DescribeBarrierGroupsRequest::default(), version);
264 roundtrip(&DescribeBarrierGroupsResponse::default(), version);
265 }
266 }
267
268 #[test]
269 fn populated_roundtrips_all_versions() {
270 for version in MIN_VERSION..=MAX_VERSION {
271 roundtrip(&DescribeBarrierGroupsRequest::populated(), version);
272 roundtrip(&DescribeBarrierGroupsResponse::populated(), version);
273 }
274 }
275
276 #[test]
277 fn empty_group_list_asks_for_every_group() {
278 let request = DescribeBarrierGroupsRequest::default();
279 assert!(request.groups.is_empty());
280 roundtrip(&request, MIN_VERSION);
281 }
282
283 #[test]
284 fn rejects_unsupported_versions() {
285 for version in unsupported_versions(MIN_VERSION, MAX_VERSION) {
286 let response = DescribeBarrierGroupsResponse::populated();
287 assert!(matches!(
288 response.encode(&mut Vec::<u8>::new(), version),
289 Err(ProtocolError::UnsupportedVersion {
290 api_key: API_KEY,
291 ..
292 })
293 ));
294 }
295 }
296}