kafrust_protocol/codec/
encode.rs1use 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}