Skip to main content

kafrust_protocol/codec/
encode.rs

1use crate::error::{Error, Result};
2
3#[derive(Debug, Clone, Default)]
4pub struct Encoder {
5    output: Vec<u8>,
6}
7
8impl Encoder {
9    pub fn new() -> Self {
10        Self::default()
11    }
12
13    pub fn into_bytes(self) -> Vec<u8> {
14        self.output
15    }
16
17    pub fn write_i8(&mut self, value: i8) {
18        self.output.push(value as u8);
19    }
20
21    pub fn write_bool(&mut self, value: bool) {
22        self.write_i8(if value { 1 } else { 0 });
23    }
24
25    pub fn write_i16(&mut self, value: i16) {
26        self.output.extend_from_slice(&value.to_be_bytes());
27    }
28
29    pub fn write_i32(&mut self, value: i32) {
30        self.output.extend_from_slice(&value.to_be_bytes());
31    }
32
33    pub fn write_i64(&mut self, value: i64) {
34        self.output.extend_from_slice(&value.to_be_bytes());
35    }
36
37    pub fn write_f64(&mut self, value: f64) {
38        self.output
39            .extend_from_slice(&value.to_bits().to_be_bytes());
40    }
41
42    pub fn write_string(&mut self, value: &str) -> Result<()> {
43        let length = i16::try_from(value.len()).map_err(|_| Error::LengthOverflow("string"))?;
44        self.write_i16(length);
45        self.output.extend_from_slice(value.as_bytes());
46        Ok(())
47    }
48
49    pub fn write_nullable_string(&mut self, value: Option<&str>) -> Result<()> {
50        match value {
51            Some(value) => self.write_string(value),
52            None => {
53                self.write_i16(-1);
54                Ok(())
55            }
56        }
57    }
58
59    pub fn write_bytes(&mut self, value: &[u8]) -> Result<()> {
60        let length = i32::try_from(value.len()).map_err(|_| Error::LengthOverflow("bytes"))?;
61        self.write_i32(length);
62        self.output.extend_from_slice(value);
63        Ok(())
64    }
65
66    pub fn write_nullable_bytes(&mut self, value: Option<&[u8]>) -> Result<()> {
67        match value {
68            Some(value) => self.write_bytes(value),
69            None => {
70                self.write_i32(-1);
71                Ok(())
72            }
73        }
74    }
75
76    pub fn write_unsigned_varint(&mut self, mut value: u32) {
77        loop {
78            let mut byte = (value & 0x7f) as u8;
79            value >>= 7;
80            if value != 0 {
81                byte |= 0x80;
82            }
83            self.output.push(byte);
84            if value == 0 {
85                break;
86            }
87        }
88    }
89
90    pub fn write_varint(&mut self, value: i32) {
91        self.write_unsigned_varint(((value as u32) << 1) ^ ((value >> 31) as u32));
92    }
93
94    pub fn write_varlong(&mut self, value: i64) {
95        let mut value = ((value as u64) << 1) ^ ((value >> 63) as u64);
96        loop {
97            let mut byte = (value & 0x7f) as u8;
98            value >>= 7;
99            if value != 0 {
100                byte |= 0x80;
101            }
102            self.output.push(byte);
103            if value == 0 {
104                break;
105            }
106        }
107    }
108
109    pub fn write_varint_bytes(&mut self, value: &[u8]) -> Result<()> {
110        let length =
111            i32::try_from(value.len()).map_err(|_| Error::LengthOverflow("varint bytes"))?;
112        self.write_varint(length);
113        self.output.extend_from_slice(value);
114        Ok(())
115    }
116
117    pub fn write_varint_nullable_bytes(&mut self, value: Option<&[u8]>) -> Result<()> {
118        match value {
119            Some(value) => self.write_varint_bytes(value),
120            None => {
121                self.write_varint(-1);
122                Ok(())
123            }
124        }
125    }
126
127    pub fn write_compact_string(&mut self, value: &str) -> Result<()> {
128        let length =
129            u32::try_from(value.len()).map_err(|_| Error::LengthOverflow("compact string"))?;
130        let encoded_length = length
131            .checked_add(1)
132            .ok_or(Error::LengthOverflow("compact string"))?;
133        self.write_unsigned_varint(encoded_length);
134        self.output.extend_from_slice(value.as_bytes());
135        Ok(())
136    }
137
138    pub fn write_compact_nullable_string(&mut self, value: Option<&str>) -> Result<()> {
139        match value {
140            Some(value) => self.write_compact_string(value),
141            None => {
142                self.write_unsigned_varint(0);
143                Ok(())
144            }
145        }
146    }
147
148    pub fn write_compact_bytes(&mut self, value: &[u8]) -> Result<()> {
149        let length =
150            u32::try_from(value.len()).map_err(|_| Error::LengthOverflow("compact bytes"))?;
151        let encoded_length = length
152            .checked_add(1)
153            .ok_or(Error::LengthOverflow("compact bytes"))?;
154        self.write_unsigned_varint(encoded_length);
155        self.output.extend_from_slice(value);
156        Ok(())
157    }
158
159    pub fn write_compact_nullable_bytes(&mut self, value: Option<&[u8]>) -> Result<()> {
160        match value {
161            Some(value) => self.write_compact_bytes(value),
162            None => {
163                self.write_unsigned_varint(0);
164                Ok(())
165            }
166        }
167    }
168
169    pub fn write_array<T>(
170        &mut self,
171        values: Option<&[T]>,
172        mut write_item: impl FnMut(&mut Self, &T) -> Result<()>,
173    ) -> Result<()> {
174        match values {
175            Some(values) => {
176                let length =
177                    i32::try_from(values.len()).map_err(|_| Error::LengthOverflow("array"))?;
178                self.write_i32(length);
179                for value in values {
180                    write_item(self, value)?;
181                }
182            }
183            None => self.write_i32(-1),
184        }
185        Ok(())
186    }
187
188    pub fn write_compact_array<T>(
189        &mut self,
190        values: Option<&[T]>,
191        mut write_item: impl FnMut(&mut Self, &T) -> Result<()>,
192    ) -> Result<()> {
193        match values {
194            Some(values) => {
195                let length =
196                    u32::try_from(values.len()).map_err(|_| Error::LengthOverflow("array"))?;
197                let encoded_length = length
198                    .checked_add(1)
199                    .ok_or(Error::LengthOverflow("compact array"))?;
200                self.write_unsigned_varint(encoded_length);
201                for value in values {
202                    write_item(self, value)?;
203                }
204            }
205            None => self.write_unsigned_varint(0),
206        }
207        Ok(())
208    }
209
210    pub fn write_empty_tagged_fields(&mut self) {
211        self.write_unsigned_varint(0);
212    }
213
214    pub fn write_raw(&mut self, bytes: &[u8]) {
215        self.output.extend_from_slice(bytes);
216    }
217}