gin_tonic_core/
encoder.rs

1#![allow(clippy::cast_possible_truncation)]
2
3use crate::{
4    tag::Tag,
5    types::{sizeof_varint32, sizeof_varint64, PbType},
6};
7
8/// main encode trait, currently implement for anything that implements [bytes::BufMut] and [SizeHint]
9pub 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    // TODO: encode_fn and size_fn are actually the same, but generics need to be adjusted
50    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)]
226/// an [Encode] implementation that does not actually encode data but calculates the size it will need
227pub 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    // not using the constants as testing against protobuf pal would get difficult then
337    #![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}