1const VARINT: u32 = 0;
20const FIXED64: u32 = 1;
21const FIXED32: u32 = 5;
22const LENGTH_DELIMITED: u32 = 2;
23
24#[derive(Debug, Default, Clone)]
31pub struct Encoder {
32 bytes: Vec<u8>,
33}
34
35impl Encoder {
36 pub fn new() -> Self {
37 Encoder::default()
38 }
39
40 pub fn into_bytes(self) -> Vec<u8> {
41 self.bytes
42 }
43
44 pub fn as_bytes(&self) -> &[u8] {
45 &self.bytes
46 }
47
48 pub fn len(&self) -> usize {
49 self.bytes.len()
50 }
51
52 pub fn is_empty(&self) -> bool {
53 self.bytes.is_empty()
54 }
55
56 fn tag(&mut self, field: u32, wire: u32) {
58 self.raw_varint(u64::from(field) << 3 | u64::from(wire));
59 }
60
61 fn raw_varint(&mut self, mut value: u64) {
63 while value >= 0x80 {
64 self.bytes.push((value as u8) | 0x80);
65 value >>= 7;
66 }
67 self.bytes.push(value as u8);
68 }
69
70 pub fn uint64(&mut self, field: u32, value: u64) {
74 if value != 0 {
75 self.tag(field, VARINT);
76 self.raw_varint(value);
77 }
78 }
79
80 pub fn uint32(&mut self, field: u32, value: u32) {
81 self.uint64(field, u64::from(value));
82 }
83
84 pub fn int64(&mut self, field: u32, value: i64) {
88 if value != 0 {
89 self.tag(field, VARINT);
90 self.raw_varint(value as u64);
91 }
92 }
93
94 pub fn bool(&mut self, field: u32, value: bool) {
95 if value {
96 self.bool_present(field, value);
97 }
98 }
99
100 pub fn bool_present(&mut self, field: u32, value: bool) {
110 self.tag(field, VARINT);
111 self.raw_varint(u64::from(value));
112 }
113
114 pub fn int64_present(&mut self, field: u32, value: i64) {
116 self.tag(field, VARINT);
117 self.raw_varint(value as u64);
118 }
119
120 pub fn string_present(&mut self, field: u32, value: &str) {
122 self.tag(field, LENGTH_DELIMITED);
123 self.raw_varint(value.len() as u64);
124 self.bytes.extend_from_slice(value.as_bytes());
125 }
126
127 pub fn sfixed64_present(&mut self, field: u32, value: i64) {
129 self.tag(field, FIXED64);
130 self.bytes.extend_from_slice(&value.to_le_bytes());
131 }
132
133 pub fn enumeration(&mut self, field: u32, value: i32) {
136 if value != 0 {
137 self.tag(field, VARINT);
138 self.raw_varint(value as u32 as u64);
139 }
140 }
141
142 pub fn fixed64(&mut self, field: u32, value: u64) {
146 if value != 0 {
147 self.tag(field, FIXED64);
148 self.bytes.extend_from_slice(&value.to_le_bytes());
149 }
150 }
151
152 pub fn fixed32(&mut self, field: u32, value: u32) {
155 if value != 0 {
156 self.tag(field, FIXED32);
157 self.bytes.extend_from_slice(&value.to_le_bytes());
158 }
159 }
160
161 pub fn sfixed64(&mut self, field: u32, value: i64) {
163 if value != 0 {
164 self.tag(field, FIXED64);
165 self.bytes.extend_from_slice(&value.to_le_bytes());
166 }
167 }
168
169 pub fn double(&mut self, field: u32, value: f64) {
171 if value != 0.0 {
172 self.present_double(field, value);
173 }
174 }
175
176 pub fn present_double(&mut self, field: u32, value: f64) {
184 self.tag(field, FIXED64);
185 self.bytes.extend_from_slice(&value.to_le_bytes());
186 }
187
188 pub fn string(&mut self, field: u32, value: &str) {
190 if !value.is_empty() {
191 self.bytes_field(field, value.as_bytes());
192 }
193 }
194
195 pub fn bytes_field(&mut self, field: u32, value: &[u8]) {
197 if value.is_empty() {
198 return;
199 }
200 self.tag(field, LENGTH_DELIMITED);
201 self.raw_varint(value.len() as u64);
202 self.bytes.extend_from_slice(value);
203 }
204
205 pub fn message(&mut self, field: u32, message: &Encoder) {
212 self.tag(field, LENGTH_DELIMITED);
213 self.raw_varint(message.bytes.len() as u64);
214 self.bytes.extend_from_slice(&message.bytes);
215 }
216
217 pub fn packed_fixed64(&mut self, field: u32, values: &[u64]) {
223 if values.is_empty() {
224 return;
225 }
226 self.tag(field, LENGTH_DELIMITED);
227 self.raw_varint((values.len() * 8) as u64);
228 for value in values {
229 self.bytes.extend_from_slice(&value.to_le_bytes());
230 }
231 }
232
233 pub fn packed_double(&mut self, field: u32, values: &[f64]) {
235 if values.is_empty() {
236 return;
237 }
238 self.tag(field, LENGTH_DELIMITED);
239 self.raw_varint((values.len() * 8) as u64);
240 for value in values {
241 self.bytes.extend_from_slice(&value.to_le_bytes());
242 }
243 }
244}
245
246#[cfg(test)]
247mod tests {
248 use super::*;
249
250 fn varint_of(value: u64) -> Vec<u8> {
251 let mut encoder = Encoder::new();
252 encoder.raw_varint(value);
253 encoder.into_bytes()
254 }
255
256 #[test]
260 fn varints_match_the_specifications_worked_example() {
261 assert_eq!(varint_of(0), [0x00]);
262 assert_eq!(varint_of(1), [0x01]);
263 assert_eq!(varint_of(127), [0x7f]);
264 assert_eq!(varint_of(128), [0x80, 0x01]);
265 assert_eq!(varint_of(300), [0xac, 0x02]);
266 assert_eq!(varint_of(u64::MAX), [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01]);
267 }
268
269 #[test]
272 fn a_tagged_varint_field_is_the_canonical_three_bytes() {
273 let mut encoder = Encoder::new();
274 encoder.uint64(1, 150);
275
276 assert_eq!(encoder.as_bytes(), [0x08, 0x96, 0x01]);
277 }
278
279 #[test]
282 fn a_string_field_is_tag_length_then_utf8() {
283 let mut encoder = Encoder::new();
284 encoder.string(2, "testing");
285
286 assert_eq!(encoder.as_bytes(), b"\x12\x07testing");
287 }
288
289 #[test]
290 fn a_nested_message_is_length_delimited_around_its_own_bytes() {
291 let mut inner = Encoder::new();
292 inner.uint64(1, 150);
293
294 let mut outer = Encoder::new();
295 outer.message(3, &inner);
296
297 assert_eq!(outer.as_bytes(), [0x1a, 0x03, 0x08, 0x96, 0x01]);
299 }
300
301 #[test]
304 fn an_empty_nested_message_still_writes_its_header() {
305 let mut outer = Encoder::new();
306 outer.message(15, &Encoder::new());
307
308 assert_eq!(outer.as_bytes(), [0x7a, 0x00]);
309 }
310
311 #[test]
312 fn fixed64_is_eight_little_endian_bytes() {
313 let mut encoder = Encoder::new();
314 encoder.fixed64(7, 1);
316
317 assert_eq!(encoder.as_bytes(), [0x39, 0x01, 0, 0, 0, 0, 0, 0, 0]);
318 }
319
320 #[test]
321 fn a_double_is_its_ieee_754_bits_little_endian() {
322 let mut encoder = Encoder::new();
323 encoder.double(4, 1.0);
325
326 assert_eq!(encoder.as_bytes(), [0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f]);
327 }
328
329 #[test]
332 fn zero_is_skipped_by_double_and_kept_by_present_double() {
333 let mut skipped = Encoder::new();
334 skipped.double(5, 0.0);
335 assert!(skipped.is_empty());
336
337 let mut kept = Encoder::new();
338 kept.present_double(5, 0.0);
339 assert_eq!(kept.as_bytes(), [0x29, 0, 0, 0, 0, 0, 0, 0, 0]);
340 }
341
342 #[test]
346 fn oneof_members_are_written_even_when_they_hold_the_default() {
347 let mut boolean = Encoder::new();
348 boolean.bool(2, false);
349 assert!(boolean.is_empty());
350 boolean.bool_present(2, false);
351 assert_eq!(boolean.as_bytes(), [0x10, 0x00]);
352
353 let mut integer = Encoder::new();
354 integer.int64_present(3, 0);
355 assert_eq!(integer.as_bytes(), [0x18, 0x00]);
356
357 let mut text = Encoder::new();
358 text.string_present(1, "");
359 assert_eq!(text.as_bytes(), [0x0a, 0x00]);
360
361 let mut number = Encoder::new();
362 number.sfixed64_present(6, 0);
363 assert_eq!(number.as_bytes(), [0x31, 0, 0, 0, 0, 0, 0, 0, 0]);
364 }
365
366 #[test]
370 fn a_negative_int64_sign_extends_to_ten_bytes() {
371 let mut encoder = Encoder::new();
372 encoder.int64(1, -1);
373
374 assert_eq!(encoder.as_bytes(), [0x08, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01]);
375 }
376
377 #[test]
378 fn packed_repeated_scalars_share_one_tag_and_one_length() {
379 let mut encoder = Encoder::new();
380 encoder.packed_fixed64(6, &[1, 2]);
382
383 let mut expected = vec![0x32, 0x10];
384 expected.extend_from_slice(&1u64.to_le_bytes());
385 expected.extend_from_slice(&2u64.to_le_bytes());
386 assert_eq!(encoder.as_bytes(), expected.as_slice());
387 }
388
389 #[test]
390 fn packed_doubles_are_bounds_as_the_collector_expects_them() {
391 let mut encoder = Encoder::new();
392 encoder.packed_double(7, &[0.005, 0.01]);
393
394 let mut expected = vec![0x3a, 0x10];
395 expected.extend_from_slice(&0.005f64.to_le_bytes());
396 expected.extend_from_slice(&0.01f64.to_le_bytes());
397 assert_eq!(encoder.as_bytes(), expected.as_slice());
398 }
399
400 #[test]
403 fn default_values_are_omitted_entirely() {
404 let mut encoder = Encoder::new();
405 encoder.uint64(1, 0);
406 encoder.int64(2, 0);
407 encoder.bool(3, false);
408 encoder.enumeration(4, 0);
409 encoder.fixed64(5, 0);
410 encoder.string(6, "");
411 encoder.bytes_field(7, &[]);
412 encoder.packed_fixed64(8, &[]);
413
414 assert!(encoder.is_empty());
415 }
416
417 #[test]
420 fn field_numbers_past_fifteen_use_a_two_byte_tag() {
421 let mut encoder = Encoder::new();
422 encoder.uint64(16, 1);
423
424 assert_eq!(encoder.as_bytes(), [0x80, 0x01, 0x01]);
426 }
427}