Skip to main content

kafrust_protocol/api/
describe_client_quotas.rs

1use crate::codec::{Decoder, Encoder};
2use crate::error::Result;
3use crate::header::RequestHeader;
4
5pub const API_KEY: i16 = 48;
6
7#[derive(Debug, Clone, PartialEq, Eq)]
8pub struct DescribeClientQuotasRequestV0 {
9    pub correlation_id: i32,
10    pub client_id: Option<String>,
11    pub components: Vec<DescribeClientQuotasComponentV0>,
12    pub strict: bool,
13}
14
15impl DescribeClientQuotasRequestV0 {
16    pub fn encode(&self) -> Result<Vec<u8>> {
17        let mut encoder = Encoder::new();
18        RequestHeader {
19            api_key: API_KEY,
20            api_version: 0,
21            correlation_id: self.correlation_id,
22            client_id: self.client_id.clone(),
23        }
24        .encode_v1(&mut encoder)?;
25        encoder.write_array(Some(&self.components), |encoder, component| {
26            encoder.write_string(&component.entity_type)?;
27            encoder.write_i8(component.match_type);
28            encoder.write_nullable_string(component.match_value.as_deref())?;
29            Ok(())
30        })?;
31        encoder.write_bool(self.strict);
32        Ok(encoder.into_bytes())
33    }
34}
35
36#[derive(Debug, Clone, PartialEq, Eq)]
37pub struct DescribeClientQuotasComponentV0 {
38    pub entity_type: String,
39    pub match_type: i8,
40    pub match_value: Option<String>,
41}
42
43#[derive(Debug, Clone, PartialEq)]
44pub struct DescribeClientQuotasResponseV0 {
45    pub throttle_time_ms: i32,
46    pub error_code: i16,
47    pub error_message: Option<String>,
48    pub entries: Vec<DescribeClientQuotasEntryV0>,
49}
50
51impl DescribeClientQuotasResponseV0 {
52    pub fn decode_body(decoder: &mut Decoder<'_>) -> Result<Self> {
53        Ok(Self {
54            throttle_time_ms: decoder.read_i32()?,
55            error_code: decoder.read_i16()?,
56            error_message: decoder.read_nullable_string()?,
57            entries: decoder
58                .read_array(
59                    "describe client quota entries",
60                    DescribeClientQuotasEntryV0::decode,
61                )?
62                .unwrap_or_default(),
63        })
64    }
65}
66
67#[derive(Debug, Clone, PartialEq)]
68pub struct DescribeClientQuotasEntryV0 {
69    pub entities: Vec<DescribeClientQuotasEntityV0>,
70    pub values: Vec<DescribeClientQuotasValueV0>,
71}
72
73impl DescribeClientQuotasEntryV0 {
74    fn decode(decoder: &mut Decoder<'_>) -> Result<Self> {
75        Ok(Self {
76            entities: decoder
77                .read_array(
78                    "describe client quota entities",
79                    DescribeClientQuotasEntityV0::decode,
80                )?
81                .unwrap_or_default(),
82            values: decoder
83                .read_array(
84                    "describe client quota values",
85                    DescribeClientQuotasValueV0::decode,
86                )?
87                .unwrap_or_default(),
88        })
89    }
90}
91
92#[derive(Debug, Clone, PartialEq, Eq)]
93pub struct DescribeClientQuotasEntityV0 {
94    pub entity_type: String,
95    pub entity_name: Option<String>,
96}
97
98impl DescribeClientQuotasEntityV0 {
99    fn decode(decoder: &mut Decoder<'_>) -> Result<Self> {
100        Ok(Self {
101            entity_type: decoder.read_string()?,
102            entity_name: decoder.read_nullable_string()?,
103        })
104    }
105}
106
107#[derive(Debug, Clone, PartialEq)]
108pub struct DescribeClientQuotasValueV0 {
109    pub key: String,
110    pub value: f64,
111}
112
113impl DescribeClientQuotasValueV0 {
114    fn decode(decoder: &mut Decoder<'_>) -> Result<Self> {
115        Ok(Self {
116            key: decoder.read_string()?,
117            value: decoder.read_f64()?,
118        })
119    }
120}
121
122#[cfg(test)]
123#[allow(clippy::unwrap_used)]
124mod tests {
125    use super::{
126        DescribeClientQuotasComponentV0, DescribeClientQuotasRequestV0,
127        DescribeClientQuotasResponseV0, API_KEY,
128    };
129    use crate::codec::{Decoder, Encoder};
130
131    #[test]
132    fn encodes_describe_client_quotas_v0_request() {
133        let request = DescribeClientQuotasRequestV0 {
134            correlation_id: 17,
135            client_id: Some("kafrust".to_owned()),
136            components: vec![DescribeClientQuotasComponentV0 {
137                entity_type: "user".to_owned(),
138                match_type: 0,
139                match_value: Some("alice".to_owned()),
140            }],
141            strict: true,
142        };
143
144        let bytes = request.encode().unwrap();
145        assert_eq!(&bytes[0..4], &[0, API_KEY as u8, 0, 0]);
146        assert_eq!(&bytes[4..8], &[0, 0, 0, 17]);
147        assert_eq!(bytes.last(), Some(&1));
148    }
149
150    #[test]
151    fn decodes_describe_client_quotas_v0_response() {
152        let mut bytes = Encoder::new();
153        bytes.write_i32(7);
154        bytes.write_i16(0);
155        bytes.write_nullable_string(None).unwrap();
156        bytes.write_i32(1);
157        bytes.write_i32(1);
158        bytes.write_string("user").unwrap();
159        bytes.write_nullable_string(Some("alice")).unwrap();
160        bytes.write_i32(1);
161        bytes.write_string("producer_byte_rate").unwrap();
162        bytes.write_f64(1024.5);
163        let bytes = bytes.into_bytes();
164        let mut decoder = Decoder::new(&bytes);
165
166        let response = DescribeClientQuotasResponseV0::decode_body(&mut decoder).unwrap();
167
168        assert_eq!(response.throttle_time_ms, 7);
169        assert_eq!(response.entries[0].entities[0].entity_type, "user");
170        assert_eq!(
171            response.entries[0].entities[0].entity_name.as_deref(),
172            Some("alice")
173        );
174        assert_eq!(response.entries[0].values[0].key, "producer_byte_rate");
175        assert_eq!(response.entries[0].values[0].value, 1024.5);
176        assert!(decoder.is_empty());
177    }
178}