1#![allow(clippy::cast_possible_truncation)]
2
3use crate::{
4 tag::Tag,
5 types::{sizeof_varint32, sizeof_varint64, PbType},
6};
7
8pub trait Encode {
10 fn encode_float(&mut self, n: f32);
11 fn encode_double(&mut self, n: f64);
12
13 fn encode_varint(&mut self, n: u64);
14
15 fn encode_int32(&mut self, n: i32);
16 fn encode_int64(&mut self, n: i64);
17
18 fn encode_uint32(&mut self, n: u32);
19 fn encode_uint64(&mut self, n: u64);
20
21 fn encode_sint32(&mut self, n: i32);
22 fn encode_sint64(&mut self, n: i64);
23
24 fn encode_fixed32(&mut self, n: u32);
25 fn encode_fixed64(&mut self, n: u64);
26
27 fn encode_sfixed32(&mut self, n: i32);
28 fn encode_sfixed64(&mut self, n: i64);
29
30 fn encode_bool(&mut self, b: bool);
31 fn encode_bytes(&mut self, b: &[u8]);
32 fn encode_str(&mut self, s: &str);
33 fn encode_string(&mut self, s: String) {
34 self.encode_str(&s)
35 }
36
37 fn encode_nested(&mut self, msg: &impl PbType)
38 where
39 Self: Sized,
40 {
41 let size = msg.size_hint();
42
43 self.encode_uint32(size as _);
44 msg.encode(self);
45 }
46
47 fn encode_type(&mut self, msg: &impl PbType);
48
49 fn encode_packed<M, F, FS>(&mut self, items: &[M], mut encode_fn: F, mut size_fn: FS)
51 where
52 M: Clone,
53 F: FnMut(&mut Self, M),
54 FS: FnMut(&mut SizeHint, M),
55 {
56 let mut hint = SizeHint::default();
57 for item in items {
58 size_fn(&mut hint, item.clone())
59 }
60 self.encode_uint32(hint.size() as _);
61 for item in items {
62 encode_fn(self, item.clone());
63 }
64 }
65
66 #[allow(clippy::too_many_arguments)]
67 fn encode_map_element<K, V, FK, FV, FSK, FSV>(
68 &mut self,
69 key: K,
70 value: V,
71 key_wire_type: u8,
72 value_wire_type: u8,
73 mut key_encode_fn: FK,
74 mut value_encode_fn: FV,
75 mut key_size_fn: FSK,
76 mut value_size_fn: FSV,
77 ) where
78 K: Clone,
79 FK: FnMut(&mut Self, K),
80 FSK: FnMut(&mut SizeHint, K),
81 V: Clone,
82 FV: FnMut(&mut Self, V),
83 FSV: FnMut(&mut SizeHint, V),
84 {
85 let mut hint = SizeHint::default();
86
87 hint.encode_uint32(u32::from_parts(1, key_wire_type));
88 key_size_fn(&mut hint, key.clone());
89 hint.encode_uint32(u32::from_parts(2, value_wire_type));
90 value_size_fn(&mut hint, value.clone());
91
92 self.encode_uint32(hint.size() as _);
93 self.encode_uint32(u32::from_parts(1, key_wire_type));
94 key_encode_fn(self, key.clone());
95 self.encode_uint32(u32::from_parts(2, value_wire_type));
96 value_encode_fn(self, value.clone());
97 }
98}
99
100#[inline]
101fn zigzag_encode(from: i64) -> u64 {
102 ((from << 1) ^ (from >> 63)) as u64
103}
104
105impl<T> Encode for T
106where
107 T: bytes::BufMut,
108{
109 #[inline]
110 fn encode_float(&mut self, n: f32) {
111 self.put_f32_le(n)
112 }
113
114 #[inline]
115 fn encode_double(&mut self, n: f64) {
116 self.put_f64_le(n)
117 }
118
119 #[inline]
120 fn encode_varint(&mut self, mut n: u64) {
121 while n >= 0x80 {
122 self.put_u8(0x80 | (n as u8));
123 n >>= 7;
124 }
125
126 self.put_u8(n as u8);
127 }
128
129 #[inline]
130 fn encode_int32(&mut self, n: i32) {
131 let negative = n < 0;
132 let mut n = n as u32;
133
134 if n <= 0x7F {
135 return self.put_u8(n as u8);
136 }
137
138 loop {
139 let mut b = (n as u8) & 0x7F;
140 n >>= 7;
141 if n != 0 {
142 b |= 0x80;
143 } else if negative {
144 b |= 0b11110000;
145 }
146 self.put_u8(b);
147
148 if n == 0 {
149 break;
150 }
151 }
152
153 if negative {
154 self.put([0xFF, 0xFF, 0xFF, 0xFF, 0x01].as_ref());
155 }
156 }
157
158 #[inline]
159 fn encode_int64(&mut self, n: i64) {
160 self.encode_varint(n as u64);
161 }
162
163 #[inline]
164 fn encode_uint32(&mut self, n: u32) {
165 self.encode_varint(n as u64);
166 }
167
168 #[inline]
169 fn encode_uint64(&mut self, n: u64) {
170 self.encode_varint(n);
171 }
172
173 #[inline]
174 fn encode_sint32(&mut self, n: i32) {
175 self.encode_varint(zigzag_encode(n as i64));
176 }
177
178 #[inline]
179 fn encode_sint64(&mut self, n: i64) {
180 self.encode_varint(zigzag_encode(n));
181 }
182
183 #[inline]
184 fn encode_fixed32(&mut self, n: u32) {
185 self.put_u32_le(n);
186 }
187
188 #[inline]
189 fn encode_fixed64(&mut self, n: u64) {
190 self.put_u64_le(n);
191 }
192
193 #[inline]
194 fn encode_sfixed32(&mut self, n: i32) {
195 self.put_i32_le(n);
196 }
197
198 #[inline]
199 fn encode_sfixed64(&mut self, n: i64) {
200 self.put_i64_le(n);
201 }
202
203 #[inline]
204 fn encode_bool(&mut self, b: bool) {
205 self.put_u8(b as u8);
206 }
207
208 #[inline]
209 fn encode_bytes(&mut self, b: &[u8]) {
210 self.encode_uint32(b.len() as u32);
211 self.put(b);
212 }
213
214 #[inline]
215 fn encode_str(&mut self, s: &str) {
216 self.encode_bytes(s.as_bytes());
217 }
218
219 #[inline]
220 fn encode_type(&mut self, ty: &impl PbType) {
221 ty.encode(self)
222 }
223}
224
225#[derive(Debug, Default)]
226pub struct SizeHint {
228 size: usize,
229}
230
231impl SizeHint {
232 pub fn clear(&mut self) {
233 self.size = 0;
234 }
235
236 #[inline]
237 pub fn size(&self) -> usize {
238 self.size
239 }
240}
241
242impl Encode for SizeHint {
243 #[inline]
244 fn encode_float(&mut self, _n: f32) {
245 self.size += std::mem::size_of::<f32>();
246 }
247
248 #[inline]
249 fn encode_double(&mut self, _n: f64) {
250 self.size += std::mem::size_of::<f64>();
251 }
252
253 #[inline]
254 fn encode_varint(&mut self, n: u64) {
255 self.size += sizeof_varint64(n);
256 }
257
258 #[inline]
259 fn encode_int32(&mut self, n: i32) {
260 if n < 0 {
261 self.size += 10;
262 } else {
263 self.encode_varint(n as _);
264 }
265 }
266
267 #[inline]
268 fn encode_int64(&mut self, n: i64) {
269 self.encode_varint(n as _);
270 }
271
272 #[inline]
273 fn encode_uint32(&mut self, n: u32) {
274 self.size += sizeof_varint32(n);
275 }
276
277 #[inline]
278 fn encode_uint64(&mut self, n: u64) {
279 self.encode_varint(n as _);
280 }
281
282 #[inline]
283 fn encode_sint32(&mut self, n: i32) {
284 self.size += sizeof_varint32(zigzag_encode(n as i64) as u32);
285 }
286
287 #[inline]
288 fn encode_sint64(&mut self, n: i64) {
289 self.encode_varint(zigzag_encode(n));
290 }
291
292 #[inline]
293 fn encode_fixed32(&mut self, _n: u32) {
294 self.size += std::mem::size_of::<u32>();
295 }
296
297 #[inline]
298 fn encode_fixed64(&mut self, _n: u64) {
299 self.size += std::mem::size_of::<u64>();
300 }
301
302 #[inline]
303 fn encode_sfixed32(&mut self, _n: i32) {
304 self.size += std::mem::size_of::<i32>();
305 }
306
307 #[inline]
308 fn encode_sfixed64(&mut self, _n: i64) {
309 self.size += std::mem::size_of::<i64>();
310 }
311
312 #[inline]
313 fn encode_bool(&mut self, _b: bool) {
314 self.size += 1;
315 }
316
317 #[inline]
318 fn encode_bytes(&mut self, b: &[u8]) {
319 self.encode_uint32(b.len() as u32);
320 self.size += b.len();
321 }
322
323 #[inline]
324 fn encode_str(&mut self, s: &str) {
325 self.encode_bytes(s.as_bytes());
326 }
327
328 #[inline]
329 fn encode_type(&mut self, msg: &impl PbType) {
330 msg.encode(self)
331 }
332}
333
334#[cfg(test)]
335mod tests {
336 #![allow(clippy::approx_constant)]
338
339 use crate::{
340 encoder::SizeHint,
341 types::{
342 Fixed32, Fixed64, Int32, Int64, PbType, SFixed32, SFixed64, SInt32, SInt64, UInt32,
343 UInt64,
344 },
345 WIRE_TYPE_LENGTH_ENCODED, WIRE_TYPE_VARINT,
346 };
347
348 use super::Encode;
349
350 #[test]
351 fn encode_float() {
352 let mut buffer = bytes::BytesMut::with_capacity(4);
353 buffer.encode_float(3.14);
354 assert_eq!(3.14f32.size_hint(), 4);
355 assert_eq!(*buffer, [0xc3, 0xf5, 0x48, 0x40]);
356 }
357
358 #[test]
359 fn encode_double() {
360 let mut buffer = bytes::BytesMut::with_capacity(8);
361 buffer.encode_double(3.14);
362 assert_eq!(3.14f64.size_hint(), 8);
363 assert_eq!(*buffer, [0x1f, 0x85, 0xeb, 0x51, 0xb8, 0x1e, 0x09, 0x40]);
364 }
365
366 #[test]
367 fn encode_int32() {
368 let mut buffer = bytes::BytesMut::with_capacity(10);
369 buffer.encode_int32(1);
370 assert_eq!(Int32(1).size_hint(), 1);
371 assert_eq!(*buffer, [0x01]);
372
373 buffer.clear();
374 buffer.encode_int32(1234);
375 assert_eq!(Int32(1234).size_hint(), 2);
376 assert_eq!(*buffer, [0xd2, 0x09]);
377
378 buffer.clear();
379 buffer.encode_int32(-1234);
380 assert_eq!(Int32(-1234).size_hint(), 10);
381 assert_eq!(
382 *buffer,
383 [0xae, 0xf6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01]
384 );
385 }
386
387 #[test]
388 fn encode_int64() {
389 let mut buffer = bytes::BytesMut::with_capacity(10);
390 buffer.encode_int64(1);
391 assert_eq!(Int64(1).size_hint(), 1);
392 assert_eq!(*buffer, [0x01]);
393
394 buffer.clear();
395 buffer.encode_int64(1234);
396 assert_eq!(Int64(1234).size_hint(), 2);
397 assert_eq!(*buffer, [0xd2, 0x09]);
398
399 buffer.clear();
400 buffer.encode_int64(-1234);
401 assert_eq!(Int64(-1234).size_hint(), 10);
402 assert_eq!(
403 *buffer,
404 [0xae, 0xf6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01]
405 );
406 }
407
408 #[test]
409 fn encode_uint32() {
410 let mut buffer = bytes::BytesMut::with_capacity(10);
411 buffer.encode_uint32(1);
412 assert_eq!(UInt32(1).size_hint(), 1);
413 assert_eq!(*buffer, [0x01]);
414
415 buffer.clear();
416 buffer.encode_uint32(1234);
417 assert_eq!(UInt32(1234).size_hint(), 2);
418 assert_eq!(*buffer, [0xd2, 0x09]);
419 }
420
421 #[test]
422 fn encode_uint64() {
423 let mut buffer = bytes::BytesMut::with_capacity(10);
424 buffer.encode_uint64(1);
425 assert_eq!(UInt64(1).size_hint(), 1);
426 assert_eq!(*buffer, [0x01]);
427
428 buffer.clear();
429 buffer.encode_uint64(1234);
430 assert_eq!(UInt64(1234).size_hint(), 2);
431 assert_eq!(*buffer, [0xd2, 0x09]);
432 }
433
434 #[test]
435 fn encode_sint32() {
436 let mut buffer = bytes::BytesMut::with_capacity(10);
437 buffer.encode_sint32(1);
438 assert_eq!(SInt32(1).size_hint(), 1);
439 assert_eq!(*buffer, [0x02]);
440
441 buffer.clear();
442 buffer.encode_sint32(1234);
443 assert_eq!(SInt32(1234).size_hint(), 2);
444 assert_eq!(*buffer, [0xa4, 0x13]);
445
446 buffer.clear();
447 buffer.encode_sint32(-1234);
448 assert_eq!(SInt32(-1234).size_hint(), 2);
449 assert_eq!(*buffer, [0xa3, 0x13]);
450 }
451
452 #[test]
453 fn encode_sint64() {
454 let mut buffer = bytes::BytesMut::with_capacity(8);
455 buffer.encode_sint64(1);
456 assert_eq!(SInt64(1).size_hint(), 1);
457 assert_eq!(*buffer, [0x02]);
458
459 buffer.clear();
460 buffer.encode_sint64(1234);
461 assert_eq!(SInt64(1234).size_hint(), 2);
462 assert_eq!(*buffer, [0xa4, 0x13]);
463
464 buffer.clear();
465 buffer.encode_sint64(-1234);
466 assert_eq!(SInt64(-1234).size_hint(), 2);
467 assert_eq!(*buffer, [0xa3, 0x13]);
468 }
469
470 #[test]
471 fn encode_fixed32() {
472 let mut buffer = bytes::BytesMut::with_capacity(4);
473 buffer.encode_fixed32(1);
474 assert_eq!(Fixed32(1).size_hint(), 4);
475 assert_eq!(*buffer, [0x01, 0x00, 0x00, 0x00]);
476
477 buffer.clear();
478 buffer.encode_fixed32(1234);
479 assert_eq!(Fixed32(1234).size_hint(), 4);
480 assert_eq!(*buffer, [0xd2, 0x04, 0x00, 0x00]);
481 }
482
483 #[test]
484 fn encode_fixed64() {
485 let mut buffer = bytes::BytesMut::with_capacity(8);
486 buffer.encode_fixed64(1);
487 assert_eq!(Fixed64(1).size_hint(), 8);
488 assert_eq!(*buffer, [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
489
490 buffer.clear();
491 buffer.encode_fixed64(1234);
492 assert_eq!(Fixed64(1234).size_hint(), 8);
493 assert_eq!(*buffer, [0xd2, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
494 }
495
496 #[test]
497 fn encode_sfixed32() {
498 let mut buffer = bytes::BytesMut::with_capacity(4);
499 buffer.encode_sfixed32(1);
500 assert_eq!(SFixed32(1).size_hint(), 4);
501 assert_eq!(*buffer, [0x01, 0x00, 0x00, 0x00]);
502
503 buffer.clear();
504 buffer.encode_sfixed32(1234);
505 assert_eq!(SFixed32(1234).size_hint(), 4);
506 assert_eq!(*buffer, [0xd2, 0x04, 0x00, 0x00]);
507
508 buffer.clear();
509 buffer.encode_sfixed32(-1234);
510 assert_eq!(SFixed32(-1234).size_hint(), 4);
511 assert_eq!(*buffer, [0x2e, 0xfb, 0xff, 0xff]);
512 }
513
514 #[test]
515 fn encode_sfixed64() {
516 let mut buffer = bytes::BytesMut::with_capacity(8);
517 buffer.encode_sfixed64(1);
518 assert_eq!(SFixed64(1).size_hint(), 8);
519 assert_eq!(*buffer, [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
520
521 buffer.clear();
522 buffer.encode_sfixed64(1234);
523 assert_eq!(SFixed64(1234).size_hint(), 8);
524 assert_eq!(*buffer, [0xd2, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]);
525
526 buffer.clear();
527 buffer.encode_sfixed64(-1234);
528 assert_eq!(SFixed64(-1234).size_hint(), 8);
529 assert_eq!(*buffer, [0x2e, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]);
530 }
531
532 #[test]
533 fn encode_bool() {
534 let mut buffer = bytes::BytesMut::with_capacity(4);
535 buffer.encode_bool(false);
536 assert_eq!(false.size_hint(), 1);
537 assert_eq!(*buffer, [0x00]);
538
539 buffer.clear();
540 buffer.encode_bool(true);
541 assert_eq!(true.size_hint(), 1);
542 assert_eq!(*buffer, [0x01]);
543 }
544
545 #[test]
546 fn encode_string() {
547 let mut buffer = bytes::BytesMut::with_capacity(8);
548 let data = String::new();
549 buffer.encode_str(&data);
550 assert_eq!(PbType::size_hint(&data), 1);
551 assert_eq!(*buffer, [0x00]);
552
553 buffer.clear();
554 let data = String::from("hello");
555 buffer.encode_str(&data);
556 assert_eq!(PbType::size_hint(&data), 6);
557 assert_eq!(*buffer, [0x05, 0x68, 0x65, 0x6c, 0x6c, 0x6f]);
558 }
559
560 #[test]
561 fn encode_packed() {
562 let mut buffer = bytes::BytesMut::with_capacity(8);
563 let mut hint = SizeHint::default();
564
565 let data = vec![1, 2, 3];
566 buffer.encode_packed(&data, Encode::encode_uint32, Encode::encode_uint32);
567 hint.encode_packed(&data, Encode::encode_uint32, Encode::encode_uint32);
568
569 assert_eq!(hint.size(), 4);
570 assert_eq!(*buffer, [0x03, 0x01, 0x02, 0x03]);
571
572 buffer.clear();
573 hint.clear();
574 let data = vec![1234, 2345, 3456];
575 buffer.encode_packed(&data, Encode::encode_uint32, Encode::encode_uint32);
576 hint.encode_packed(&data, Encode::encode_uint32, Encode::encode_uint32);
577
578 assert_eq!(hint.size(), 7);
579 assert_eq!(*buffer, [0x06, 0xd2, 0x09, 0xa9, 0x12, 0x80, 0x1b]);
580 }
581
582 #[test]
583 fn encode_map_element() {
584 let mut buffer = bytes::BytesMut::with_capacity(8);
585 let mut hint = SizeHint::default();
586
587 let (key, value) = ("one", 1u32);
588
589 hint.encode_map_element(
590 key,
591 value,
592 WIRE_TYPE_LENGTH_ENCODED,
593 WIRE_TYPE_VARINT,
594 Encode::encode_str,
595 Encode::encode_uint32,
596 Encode::encode_str,
597 Encode::encode_uint32,
598 );
599 buffer.encode_map_element(
600 key,
601 value,
602 WIRE_TYPE_LENGTH_ENCODED,
603 WIRE_TYPE_VARINT,
604 Encode::encode_str,
605 Encode::encode_uint32,
606 Encode::encode_str,
607 Encode::encode_uint32,
608 );
609
610 assert_eq!(hint.size(), 8);
611 assert_eq!(*buffer, [0x07, 0x0a, 0x03, 0x6f, 0x6e, 0x65, 0x10, 0x01]);
612 }
613}