1use crate::codec::{Decoder, Encoder};
2use crate::error::Result;
3use crate::header::RequestHeader;
4
5pub const API_KEY: i16 = 14;
6
7#[derive(Debug, Clone, PartialEq, Eq)]
8pub struct SyncGroupRequestV2 {
9 pub correlation_id: i32,
10 pub client_id: Option<String>,
11 pub group_id: String,
12 pub generation_id: i32,
13 pub member_id: String,
14 pub assignments: Vec<SyncGroupAssignment>,
15}
16
17impl SyncGroupRequestV2 {
18 pub fn encode(&self) -> Result<Vec<u8>> {
19 let mut encoder = Encoder::new();
20 RequestHeader {
21 api_key: API_KEY,
22 api_version: 2,
23 correlation_id: self.correlation_id,
24 client_id: self.client_id.clone(),
25 }
26 .encode_v1(&mut encoder)?;
27 encoder.write_string(&self.group_id)?;
28 encoder.write_i32(self.generation_id);
29 encoder.write_string(&self.member_id)?;
30 encoder.write_array(Some(self.assignments.as_slice()), |encoder, assignment| {
31 assignment.encode(encoder)
32 })?;
33 Ok(encoder.into_bytes())
34 }
35}
36
37#[derive(Debug, Clone, PartialEq, Eq)]
38pub struct SyncGroupAssignment {
39 pub member_id: String,
40 pub assignment: Vec<u8>,
41}
42
43impl SyncGroupAssignment {
44 fn encode(&self, encoder: &mut Encoder) -> Result<()> {
45 encoder.write_string(&self.member_id)?;
46 encoder.write_bytes(&self.assignment)
47 }
48}
49
50#[derive(Debug, Clone, PartialEq, Eq)]
51pub struct SyncGroupResponseV2 {
52 pub throttle_time_ms: i32,
53 pub error_code: i16,
54 pub assignment: Vec<u8>,
55}
56
57impl SyncGroupResponseV2 {
58 pub fn decode_body(decoder: &mut Decoder<'_>) -> Result<Self> {
59 Ok(Self {
60 throttle_time_ms: decoder.read_i32()?,
61 error_code: decoder.read_i16()?,
62 assignment: decoder.read_bytes()?,
63 })
64 }
65}
66
67#[cfg(test)]
68#[allow(clippy::unwrap_used)]
69mod tests {
70 use super::{SyncGroupAssignment, SyncGroupRequestV2, SyncGroupResponseV2};
71 use crate::codec::{Decoder, Encoder};
72
73 #[test]
74 fn encodes_sync_group_v2_request() {
75 let request = SyncGroupRequestV2 {
76 correlation_id: 19,
77 client_id: Some("kafrust".to_owned()),
78 group_id: "orders-group".to_owned(),
79 generation_id: 7,
80 member_id: "member-a".to_owned(),
81 assignments: vec![SyncGroupAssignment {
82 member_id: "member-a".to_owned(),
83 assignment: vec![1, 2, 3],
84 }],
85 };
86
87 assert_eq!(
88 request.encode().unwrap(),
89 [
90 0, 14, 0, 2, 0, 0, 0, 19, 0, 7, b'k', b'a', b'f', b'r', b'u', b's', b't', 0, 12, b'o', b'r', b'd', b'e', b'r', b's', b'-', b'g', b'r', b'o', b'u',
95 b'p', 0, 0, 0, 7, 0, 8, b'm', b'e', b'm', b'b', b'e', b'r', b'-', b'a', 0, 0, 0, 1, 0, 8, b'm', b'e', b'm', b'b', b'e', b'r', b'-', b'a', 0, 0, 0, 3, 1, 2, 3, ]
102 );
103 }
104
105 #[test]
106 fn decodes_sync_group_v2_response() {
107 let mut bytes = Encoder::new();
108 bytes.write_i32(0);
109 bytes.write_i16(0);
110 bytes.write_bytes(&[1, 2, 3]).unwrap();
111 let bytes = bytes.into_bytes();
112
113 let mut decoder = Decoder::new(&bytes);
114 let response = SyncGroupResponseV2::decode_body(&mut decoder).unwrap();
115
116 assert_eq!(response.throttle_time_ms, 0);
117 assert_eq!(response.error_code, 0);
118 assert_eq!(response.assignment, vec![1, 2, 3]);
119 assert!(decoder.is_empty());
120 }
121}