pbf_core/
lib.rs

1#![no_std]
2#![forbid(unsafe_code)]
3#![deny(missing_docs)]
4//! The `pbf` Rust crate provides functionalities to read and write Protocol Buffers (protobuf) messages.
5//! This crate is a 0 dependency package that uses `no_std` and is intended to be used in
6//! embedded systems and WASM applications. The crate is designed to be small and efficient,
7//! with the cost of some features and flexibility. It is up to the user to create the necessary
8//! data structures and implement the `ProtoRead` and `ProtoWrite` traits in order to use it effectively.
9//!
10//! ## Usage
11//!
12//! ```rust
13//! use pbf_core::{ProtoRead, ProtoWrite, Protobuf, Field, Type};
14//!
15//! #[derive(Default)]
16//! struct TestMessage {
17//!     a: i32,
18//!     b: String,
19//! }
20//! impl TestMessage {
21//!     fn new(a: i32, b: &str) -> Self {
22//!         TestMessage { a, b: b.to_owned() }
23//!     }
24//! }
25//! impl ProtoWrite for TestMessage {
26//!     fn write(&self, pb: &mut Protobuf) {
27//!         pb.write_varint_field(1, self.a);
28//!         pb.write_string_field(2, &self.b);
29//!     }
30//! }
31//! impl ProtoRead for TestMessage {
32//!     fn read(&mut self, tag: u64, pb: &mut Protobuf) {
33//!         println!("tag: {}", tag);
34//!         match tag {
35//!             1 => self.a = pb.read_varint(),
36//!             2 => self.b = pb.read_string(),
37//!             _ => panic!("Invalid tag"),
38//!         }
39//!     }
40//! }
41//!
42//! let mut pb = Protobuf::new();
43//! let msg = TestMessage::new(1, "hello");
44//! pb.write_fields(&msg);
45//!
46//! let bytes = pb.take();
47//! let mut pb = Protobuf::from_input(bytes);
48//!
49//! let mut msg = TestMessage::default();
50//! pb.read_fields(&mut msg, None);
51//! assert_eq!(msg.a, 1);
52//! assert_eq!(msg.b, "hello");
53//! ```
54
55/// All encoding and decoding is done via u64.
56/// So all types must implement this trait to be able to be encoded and decoded.
57pub mod bit_cast;
58
59extern crate alloc;
60
61use alloc::{
62    string::{String, ToString},
63    vec::Vec,
64};
65pub use bit_cast::*;
66use core::mem::size_of;
67
68const MAX_VARINT_LENGTH: usize = u64::BITS as usize * 8 / 7 + 1;
69const BIT_SHIFT: [u64; 10] = [0, 7, 14, 21, 28, 35, 42, 49, 56, 63];
70
71/// The `Type` enum represents the different types that a field can have in a protobuf message.
72/// The `Type` enum is used to determine how to encode and decode the field.
73#[derive(Debug, PartialEq)]
74pub enum Type {
75    /// Varint may be: int32, int64, uint32, uint64, sint32, sint64, bool, enum
76    Varint = 0,
77    /// Fixed 64-bit numbers will take up exactly 64 bits of space
78    /// They may be u64, i64, or f64
79    Fixed64 = 1,
80    /// This includes any len-delimited tyles:
81    /// string, bytes, embedded messages, packed repeated fields
82    Bytes = 2,
83    /// Fixed 32-bit numbers will take up exactly 64 bits of space
84    /// They may be an u32, i32, or f32
85    Fixed32 = 5,
86    /// This is a null type
87    None = 7,
88}
89impl From<u8> for Type {
90    /// Convert a u8 to a Type
91    /// # Panics
92    /// If the value is not a valid Type
93    fn from(val: u8) -> Self {
94        match val & 0x7 {
95            0 => Type::Varint,
96            1 => Type::Fixed64,
97            2 => Type::Bytes,
98            5 => Type::Fixed32,
99            7 => Type::None,
100            _ => panic!("Invalid value for Type"),
101        }
102    }
103}
104impl From<Type> for u64 {
105    fn from(t: Type) -> Self {
106        match t {
107            Type::Varint => 0,
108            Type::Fixed64 => 1,
109            Type::Bytes => 2,
110            Type::Fixed32 => 5,
111            Type::None => 7,
112        }
113    }
114}
115
116/// The `Field` struct contains a tag and a type.
117/// The tag is used to track the data type in the message for decoding.
118/// The type is used to determine how to encode and decode the field.
119#[derive(Debug, PartialEq)]
120pub struct Field {
121    /// The tag is used to track the data type in the message for decoding.
122    pub tag: u64,
123    /// The type is used to determine how to encode and decode the field.
124    pub r#type: Type,
125}
126
127/// The `ProtoRead` trait is used to read a protobuf **message**.
128/// This crate forces the user to implement this trait in order to read a protobuf message.
129///
130/// # Example
131/// Using OSM File Format [BlobHeader](https://github.com/openstreetmap/OSM-binary/blob/65e7e976f5c8e47f057a0d921639ea8e6309ef06/osmpbf/fileformat.proto#L63) as an example:
132/// ```proto
133/// message BlobHeader {
134///     required string type = 1;
135///     optional bytes indexdata = 2;
136///     required int32 datasize = 3;
137/// }
138/// ```
139/// The user would implement the `ProtoRead` trait for the `BlobHeader` struct.
140/// ```rust
141/// use pbf_core::{ProtoRead, Protobuf};
142///
143/// struct BlobHeader {
144///     r#type: String,
145///     indexdata: Vec<u8>,
146///     datasize: i32,
147/// }
148/// impl ProtoRead for BlobHeader {
149///    fn read(&mut self, tag: u64, pbf: &mut Protobuf) {
150///       match tag {
151///          1 => self.r#type = pbf.read_string(),
152///          2 => self.indexdata = pbf.read_bytes(),
153///          3 => self.datasize = pbf.read_varint(),
154///          _ => unreachable!(),
155///       }
156///    }
157/// }
158/// ```
159/// Or let the derive macro do it for you:
160/// ```rust,ignore
161/// use pbf_derive::ProtoRead;
162///
163/// #[derive(ProtoRead)]
164/// struct BlobHeader {
165///     #[pbf(tag = 1)]
166///     r#type: String,
167///     indexdata: Vec<u8>,
168///     datasize: i32,
169/// }
170/// ```
171pub trait ProtoRead {
172    /// The `read` method is used to read a field from a protobuf message.
173    /// The `tag` parameter is used to determine which field to read into the struct.
174    /// The `pbf` parameter is used to read the data in the appropriate format.
175    ///
176    /// # Example
177    /// Using OSM File Format [BlobHeader](https://github.com/openstreetmap/OSM-binary/blob/65e7e976f5c8e47f057a0d921639ea8e6309ef06/osmpbf/fileformat.proto#L63) as an example:
178    /// ```proto
179    /// message BlobHeader {
180    ///     required string type = 1;
181    ///     optional bytes indexdata = 2;
182    ///     required int32 datasize = 3;
183    /// }
184    /// ```
185    /// An example **read** implementation for a `BlobHeader` struct:
186    /// ```rust
187    /// use pbf_core::{ProtoRead, Protobuf};
188    ///
189    /// struct BlobHeader {
190    ///     r#type: String,
191    ///     indexdata: Vec<u8>,
192    ///     datasize: i32,
193    /// }
194    /// impl ProtoRead for BlobHeader {
195    ///    fn read(&mut self, tag: u64, pbf: &mut Protobuf) {
196    ///       match tag {
197    ///          1 => self.r#type = pbf.read_string(),
198    ///          2 => self.indexdata = pbf.read_bytes(),
199    ///          3 => self.datasize = pbf.read_varint(),
200    ///          _ => unreachable!(),
201    ///       }
202    ///    }
203    /// }
204    /// ```
205    /// Or let the derive macro do it for you:
206    /// ```rust,ignore
207    /// use pbf_derive::ProtoRead;
208    ///
209    /// #[derive(ProtoRead)]
210    /// struct BlobHeader {
211    ///     #[pbf(tag = 1)]
212    ///     r#type: String,
213    ///     indexdata: Vec<u8>,
214    ///     datasize: i32,
215    /// }
216    /// ```
217    fn read(&mut self, tag: u64, pbf: &mut Protobuf);
218}
219
220/// The `ProtoWrite` trait is used to write a protobuf **message**.
221/// This crate forces the user to implement this trait in order to write a protobuf message.
222///
223/// # Example
224/// Using OSM File Format [BlobHeader](https://github.com/openstreetmap/OSM-binary/blob/65e7e976f5c8e47f057a0d921639ea8e6309ef06/osmpbf/fileformat.proto#L63) as an example:
225/// ```proto
226/// message BlobHeader {
227///     required string type = 1;
228///     optional bytes indexdata = 2;
229///     required int32 datasize = 3;
230/// }
231/// ```
232/// The user would implement the `ProtoWrite` trait for the `BlobHeader` struct.
233/// ```rust
234/// use pbf_core::{ProtoWrite, Protobuf};
235///
236/// struct BlobHeader {
237///    r#type: String,
238///   indexdata: Vec<u8>,
239///   datasize: i32,
240/// }
241/// impl ProtoWrite for BlobHeader {
242///     fn write(&self, pbf: &mut Protobuf) {
243///         pbf.write_string_field(1, &self.r#type);
244///         pbf.write_bytes_field(2, &self.indexdata);
245///         pbf.write_varint_field(3, self.datasize);
246///     }
247/// }
248/// ```
249/// Or let the derive macro do it for you:
250/// ```rust,ignore
251/// use pbf_derive::ProtoWrite;
252///
253/// #[derive(ProtoWrite)]
254/// struct BlobHeader {
255///     #[pbf(tag = 1)]
256///     r#type: String,
257///     indexdata: Vec<u8>,
258///     datasize: i32,
259/// }
260/// ```
261pub trait ProtoWrite {
262    /// The `write` method is used to write a field to a protobuf message.
263    /// The `pbf` parameter is used to write the data in the appropriate format.
264    ///
265    /// # Example
266    /// Using OSM File Format [BlobHeader](https://github.com/openstreetmap/OSM-binary/blob/65e7e976f5c8e47f057a0d921639ea8e6309ef06/osmpbf/fileformat.proto#L63) as an example:
267    /// ```proto
268    /// message BlobHeader {
269    ///     required string type = 1;
270    ///     optional bytes indexdata = 2;
271    ///     required int32 datasize = 3;
272    /// }
273    /// ```
274    /// An example **write** implementation for a `BlobHeader` struct:
275    /// ```rust
276    /// use pbf_core::{ProtoWrite, Protobuf};
277    ///
278    /// struct BlobHeader {
279    ///    r#type: String,
280    ///   indexdata: Vec<u8>,
281    ///   datasize: i32,
282    /// }
283    /// impl ProtoWrite for BlobHeader {
284    ///     fn write(&self, pbf: &mut Protobuf) {
285    ///         pbf.write_string_field(1, &self.r#type);
286    ///         pbf.write_bytes_field(2, &self.indexdata);
287    ///         pbf.write_varint_field(3, self.datasize);
288    ///     }
289    /// }
290    /// ```
291    /// Or let the derive macro do it for you:
292    /// ```rust,ignore
293    /// use pbf_derive::ProtoWrite;
294    ///
295    /// #[derive(ProtoWrite)]
296    /// struct BlobHeader {
297    ///     #[pbf(tag = 1)]
298    ///     r#type: String,
299    ///     indexdata: Vec<u8>,
300    ///     datasize: i32,
301    /// }
302    /// ```
303    fn write(&self, pbf: &mut Protobuf);
304}
305
306/// The `Protobuf` struct is used to read and write protobuf messages.
307///
308/// # Example
309/// Create a new Protobuf instance:
310/// ```rust
311/// use pbf_core::Protobuf;
312///
313/// let mut pbf = Protobuf::new();
314/// ```
315/// Create a Protobuf instance from a byte buffer:
316/// ```rust
317/// use pbf_core::Protobuf;
318///
319/// let mut buf = vec![0x0A, 0x03, 0x74, 0x65, 0x73, 0x74];
320/// let mut pbf = Protobuf::from_input(buf);
321/// // OR use the From trait
322/// // let mut pbf: Protobuf = buf.into();
323/// ```
324#[derive(Clone, Debug, Default)]
325pub struct Protobuf {
326    buf: Vec<u8>,
327    pos: usize,
328}
329impl From<Vec<u8>> for Protobuf {
330    fn from(buf: Vec<u8>) -> Protobuf {
331        Protobuf::from_input(buf)
332    }
333}
334impl Protobuf {
335    /// Create a new Protobuf instance.
336    pub fn new() -> Protobuf {
337        let buf = Vec::new();
338        Protobuf { buf, pos: 0 }
339    }
340
341    /// Create a Protobuf instance from a byte buffer.
342    pub fn from_input(buf: Vec<u8>) -> Protobuf {
343        Protobuf { buf, pos: 0 }
344    }
345
346    /// Set the position to read from the buffer next.
347    pub fn set_pos(&mut self, pos: usize) {
348        self.pos = pos;
349    }
350
351    /// get the current position
352    pub fn get_pos(&self) -> usize {
353        self.pos
354    }
355
356    /// get the length of the bufer
357    pub fn len(&self) -> usize {
358        self.buf.len()
359    }
360
361    /// check if the buffer is empty
362    pub fn is_empty(&self) -> bool {
363        self.buf.is_empty()
364    }
365
366    // === READING =================================================================
367
368    /// Decode a varint from the buffer at the current position.
369    pub fn decode_varint(&mut self) -> u64 {
370        if self.pos >= self.len() {
371            panic!("EOF");
372        }
373
374        let mut val: u64 = 0;
375
376        for (n, shift) in BIT_SHIFT.iter().enumerate().take(MAX_VARINT_LENGTH) {
377            let b = self.buf[self.pos] as u64;
378            self.pos += 1;
379            if n == 0 {
380                if b & 0x80 == 0 {
381                    return b;
382                }
383                val = b & 0x7f;
384            } else {
385                val |= (b & 0x7f) << shift;
386            }
387            if b < 0x80 {
388                break;
389            }
390        }
391
392        val
393    }
394
395    /// After reading a field, you can choose to skip it's value
396    /// in the buffer if it is not needed.
397    pub fn skip(&mut self, t: Type) {
398        match t {
399            Type::Varint => _ = self.decode_varint(),
400            Type::Fixed64 => self.pos += 8,
401            Type::Fixed32 => self.pos += 4,
402            Type::Bytes => self.pos += self.decode_varint() as usize,
403            Type::None => { /* Do nothing */ }
404        };
405    }
406
407    /// Read a field from the buffer.
408    pub fn read_field(&mut self) -> Field {
409        let val = self.decode_varint();
410        Field { tag: val >> 3, r#type: Type::from((val & 0x7) as u8) }
411    }
412
413    /// Read in bytes from the buffer.
414    pub fn read_bytes(&mut self) -> Vec<u8> {
415        let end = self.decode_varint() as usize + self.pos;
416        let bytes = self.buf[self.pos..end].to_vec();
417        self.pos += end - self.pos;
418
419        bytes
420    }
421
422    /// Read in a string from the buffer.
423    pub fn read_string(&mut self) -> String {
424        String::from_utf8_lossy(&self.read_bytes()).to_string()
425    }
426
427    /// Read in a fixed size value from the buffer.
428    pub fn read_fixed<T>(&mut self) -> T
429    where
430        T: BitCast,
431    {
432        let mut val: u64 = 0;
433        let size = size_of::<T>();
434
435        let mut n = 0;
436        while n < size {
437            val |= (self.buf[self.pos] as u64) << (n << 3);
438            self.pos += 1;
439            n += 1;
440        }
441
442        if cfg!(target_endian = "big") {
443            val = val.swap_bytes();
444        }
445
446        T::from_u64(val)
447    }
448
449    /// Read in a variable size value from the buffer.
450    pub fn read_varint<T>(&mut self) -> T
451    where
452        T: BitCast,
453    {
454        let val = self.decode_varint();
455        T::from_u64(val)
456    }
457
458    /// Read in a signed variable size value from the buffer.
459    ///
460    /// # Panics
461    /// Panics if the conversion from `i64` to `T` fails.
462    pub fn read_s_varint<T>(&mut self) -> T
463    where
464        T: TryFrom<i64>,
465    {
466        T::try_from(zagzig(self.decode_varint()))
467            .unwrap_or_else(|_| panic!("read_s_varint: Invalid conversion"))
468    }
469
470    /// Read in a packed value from the buffer.
471    pub fn read_packed<T>(&mut self) -> Vec<T>
472    where
473        T: BitCast,
474    {
475        let end = self.decode_varint() as usize + self.pos;
476        let mut res: Vec<T> = Vec::new();
477        while self.pos < end {
478            res.push(self.read_varint::<T>());
479        }
480
481        res
482    }
483
484    /// Read in a signed packed value from the buffer.
485    pub fn read_s_packed<T>(&mut self) -> Vec<T>
486    where
487        T: TryFrom<i64>,
488    {
489        let end = self.decode_varint() as usize + self.pos;
490        let mut res: Vec<T> = Vec::new();
491        while self.pos < end {
492            res.push(self.read_s_varint::<T>());
493        }
494
495        res
496    }
497
498    /// Read a message from the buffer. This is the alternative to `read_message`
499    /// which does the same thing but you may already know the size of the message.
500    /// The other case is top level data may have fields but no message length.
501    pub fn read_fields<T: ProtoRead>(&mut self, t: &mut T, end: Option<usize>) {
502        let end = end.unwrap_or(self.len());
503
504        while self.pos < end {
505            let field = self.read_field();
506            let start_pos = self.pos;
507            t.read(field.tag, self);
508            if start_pos == self.pos {
509                self.skip(field.r#type);
510            }
511        }
512    }
513
514    /// Read in an entire message from the buffer.
515    /// This is usually used to read in a struct or enum.
516    pub fn read_message<T: ProtoRead>(&mut self, t: &mut T) {
517        let end = self.decode_varint() as usize + self.pos;
518
519        self.read_fields(t, Some(end));
520    }
521
522    // === WRITING =================================================================
523
524    /// Write a u64 to the buffer.
525    pub fn write_varint<T: BitCast>(&mut self, val: T) {
526        let mut val = val.to_u64();
527
528        while val >= 0x80 {
529            self.buf.push((val & 0x7f) as u8 | 0x80);
530            val >>= 7;
531        }
532        self.buf.push(val as u8);
533    }
534
535    /// Write an i64 to the buffer.
536    pub fn write_s_varint(&mut self, val: i64) {
537        self.write_varint(zigzag(val));
538    }
539
540    /// Write a fixed size value to the buffer. This will not compress the value.
541    pub fn write_fixed<T>(&mut self, val: T)
542    where
543        T: BitCast,
544    {
545        let size = size_of::<T>();
546        let mut val: u64 = val.to_u64();
547
548        if cfg!(target_endian = "big") {
549            val = val.swap_bytes();
550        }
551
552        let mut n = 0;
553        while n < size {
554            self.buf.push((val >> (n << 3)) as u8);
555            n += 1;
556        }
557    }
558
559    /// write a field of "tag" and "type" to the buffer.
560    pub fn write_field(&mut self, tag: u64, r#type: Type) {
561        let b: u64 = (tag << 3) | Into::<u64>::into(r#type);
562        self.write_varint(b);
563    }
564
565    /// write a tag with the size of the buffer to be appended to the internal buffer.
566    pub fn write_length_varint(&mut self, tag: u64, val: usize) {
567        self.write_field(tag, Type::Bytes);
568        self.write_varint(val);
569    }
570
571    /// write a variable sized number, bool, or enum into to the buffer.
572    pub fn write_varint_field<T>(&mut self, tag: u64, val: T)
573    where
574        T: BitCast,
575    {
576        self.write_field(tag, Type::Varint);
577        self.write_varint(val);
578    }
579
580    /// write a signed variable sized number into to the buffer.
581    pub fn write_s_varint_field<T>(&mut self, tag: u64, val: T)
582    where
583        T: Into<i64>,
584    {
585        self.write_field(tag, Type::Varint);
586        self.write_s_varint(val.into());
587    }
588
589    /// write a vector packed variable sized number, bool, or enum into to the buffer.
590    pub fn write_packed_varint<T>(&mut self, tag: u64, val: &[T])
591    where
592        T: BitCast + Copy,
593    {
594        let mut pbf = Protobuf::new();
595
596        for &v in val {
597            pbf.write_varint::<T>(v);
598        }
599
600        self.write_bytes_field(tag, &(pbf.take()));
601    }
602
603    /// write a vector packed signed variable sized number into to the buffer.
604    pub fn write_packed_s_varint<T>(&mut self, tag: u64, val: &[T])
605    where
606        T: Into<i64> + Copy,
607    {
608        let mut pbf = Protobuf::new();
609
610        for &v in val {
611            pbf.write_s_varint(v.into());
612        }
613
614        self.write_bytes_field(tag, &(pbf.take()));
615    }
616
617    /// write a fixed sized number into to the buffer. No compression is done.
618    /// Supports 32 and 64 bit numbers.
619    ///
620    /// # Panics
621    /// Panics if the size of the type is not 32 or 64 bits.
622    pub fn write_fixed_field<T>(&mut self, tag: u64, val: T)
623    where
624        T: BitCast + Copy,
625    {
626        let type_ = match size_of::<T>() {
627            4 => Type::Fixed32,
628            8 => Type::Fixed64,
629            _ => panic!("Invalid fixed type"),
630        };
631
632        self.write_field(tag, type_);
633        self.write_fixed(val);
634    }
635
636    /// write only the string to the buffer
637    pub fn write_string(&mut self, val: &str) {
638        self.write_varint(val.len());
639        self.buf.extend_from_slice(val.as_bytes());
640    }
641
642    /// write a string into to the buffer.
643    pub fn write_string_field(&mut self, tag: u64, val: &str) {
644        self.write_length_varint(tag, val.len());
645        self.buf.extend_from_slice(val.as_bytes());
646    }
647
648    /// write a byte array into to the buffer.
649    pub fn write_bytes_field(&mut self, tag: u64, val: &[u8]) {
650        self.write_length_varint(tag, val.len());
651        self.buf.extend_from_slice(val)
652    }
653
654    /// write a message into to the buffer.
655    /// The message must implement the ProtoWrite trait.
656    /// This is usually reserved for structs and enums.
657    pub fn write_message<T: ProtoWrite>(&mut self, tag: u64, t: &T) {
658        let mut pbf = Protobuf::new();
659        t.write(&mut pbf);
660        let bytes = pbf.take();
661        self.write_bytes_field(tag, &bytes);
662    }
663
664    /// write a collection of fields into to the buffer.
665    /// The collection must implement the ProtoWrite trait.
666    /// This is usually reserved for top level structs and enums.
667    pub fn write_fields<T: ProtoWrite>(&mut self, t: &T) {
668        t.write(self);
669    }
670
671    /// When done writing to the buffer, call this function to take ownership
672    pub fn take(&mut self) -> Vec<u8> {
673        core::mem::take(&mut self.buf)
674    }
675}
676
677/// convert a signed integer to an unsigned integer using zigzag encoding.
678pub fn zigzag(val: i64) -> u64 {
679    ((val << 1) ^ (val >> 63)) as u64
680}
681
682/// convert an unsigned integer to a signed integer using zigzag decoding.
683pub fn zagzig(val: u64) -> i64 {
684    (val >> 1) as i64 ^ -((val & 1) as i64)
685}
686
687#[cfg(test)]
688mod tests {
689    use super::*;
690    use alloc::vec;
691
692    #[test]
693    fn it_works() {
694        let buf = vec![];
695        let pb = Protobuf::from_input(buf);
696        assert_eq!(pb.pos, 0);
697    }
698
699    #[test]
700    fn test_zigzag() {
701        assert_eq!(zigzag(0), 0);
702        assert_eq!(zagzig(0), 0);
703        assert_eq!(zagzig(zigzag(0)), 0);
704        assert_eq!(zagzig(zigzag(5)), 5);
705        assert_eq!(zagzig(zigzag(-5)), -5);
706
707        let max_i64 = i64::MAX;
708        let min_i64 = i64::MIN;
709        assert_eq!(zagzig(zigzag(max_i64)), max_i64);
710        assert_eq!(zagzig(zigzag(min_i64)), min_i64);
711    }
712
713    #[test]
714    #[should_panic(expected = "Invalid value for Type")]
715    fn test_write_field_panic() {
716        let _t: Type = Type::from(22);
717    }
718
719    #[test]
720    #[should_panic(expected = "EOF")]
721    fn test_read_past_end_panic() {
722        let mut pb = Protobuf::new();
723        pb.write_varint(1);
724        pb.write_varint(300);
725
726        let bytes = pb.take();
727        let mut pb = Protobuf::from_input(bytes);
728        pb.read_varint::<u64>();
729        pb.read_varint::<u64>();
730        pb.read_varint::<u64>();
731    }
732
733    #[test]
734    fn test_varint() {
735        let mut pb = Protobuf::new();
736        pb.write_varint(1);
737        pb.write_varint(300);
738        pb.write_varint(0x7fffffffffffffff_u64);
739
740        let bytes = pb.take();
741        assert_eq!(bytes, &[1, 172, 2, 255, 255, 255, 255, 255, 255, 255, 255, 127]);
742
743        let mut pb = Protobuf::from_input(bytes);
744        assert_eq!(pb.read_varint::<u64>(), 1);
745        assert_eq!(pb.read_varint::<u64>(), 300);
746        assert_eq!(pb.read_varint::<u64>(), 0x7fffffffffffffff);
747    }
748
749    #[test]
750    fn test_varint_field() {
751        let mut pb = Protobuf::new();
752        // unsigned
753        pb.write_varint_field(0, 5_u8);
754        pb.write_varint_field(1, 1_u16);
755        pb.write_varint_field(2, 300_u32);
756        pb.write_varint_field(3, 0x7fffffffffffffff_u64);
757        // signed
758        pb.write_varint_field(4, -5_i8);
759        pb.write_varint_field(5, -1_i16);
760        pb.write_varint_field(6, -300_i32);
761        pb.write_varint_field(7, -94949494949_i64);
762        // bool
763        pb.write_varint_field(8, true);
764        pb.write_varint_field(9, false);
765        // enum
766        #[derive(Debug, PartialEq)]
767        enum TestEnum {
768            A = 1,
769            B = 2,
770            C = 3,
771        }
772        impl BitCast for TestEnum {
773            fn from_u64(val: u64) -> Self {
774                match val {
775                    1 => TestEnum::A,
776                    2 => TestEnum::B,
777                    3 => TestEnum::C,
778                    _ => panic!("Invalid enum value"),
779                }
780            }
781            fn to_u64(&self) -> u64 {
782                match self {
783                    TestEnum::A => 1,
784                    TestEnum::B => 2,
785                    TestEnum::C => 3,
786                }
787            }
788        }
789        pb.write_varint_field(10, TestEnum::B);
790        pb.write_varint_field(11, TestEnum::A);
791        pb.write_varint_field(12, TestEnum::C);
792        // float
793        pb.write_varint_field(13, core::f32::consts::PI);
794        pb.write_varint_field(14, -core::f64::consts::PI);
795
796        let bytes = pb.take();
797        let mut pb = Protobuf::from_input(bytes);
798
799        // unsigned
800        // tag 0
801        assert_eq!(pb.read_field(), Field { tag: 0, r#type: Type::Varint });
802        assert_eq!(pb.read_varint::<u8>(), 5);
803        // tag 1
804        assert_eq!(pb.read_field(), Field { tag: 1, r#type: Type::Varint });
805        assert_eq!(pb.read_varint::<u16>(), 1);
806        // tag 2
807        assert_eq!(pb.read_field(), Field { tag: 2, r#type: Type::Varint });
808        assert_eq!(pb.read_varint::<u32>(), 300);
809        // tag 3
810        assert_eq!(pb.read_field(), Field { tag: 3, r#type: Type::Varint });
811        assert_eq!(pb.read_varint::<u64>(), 0x7fffffffffffffff);
812
813        // signed
814        // tag 4
815        assert_eq!(pb.read_field(), Field { tag: 4, r#type: Type::Varint });
816        assert_eq!(pb.read_varint::<i8>(), -5);
817        // tag 5
818        assert_eq!(pb.read_field(), Field { tag: 5, r#type: Type::Varint });
819        assert_eq!(pb.read_varint::<i16>(), -1);
820        // tag 6
821        assert_eq!(pb.read_field(), Field { tag: 6, r#type: Type::Varint });
822        assert_eq!(pb.read_varint::<i32>(), -300);
823        // tag 7
824        assert_eq!(pb.read_field(), Field { tag: 7, r#type: Type::Varint });
825        assert_eq!(pb.read_varint::<i64>(), -94949494949);
826
827        // bool
828        // tag 8
829        assert_eq!(pb.read_field(), Field { tag: 8, r#type: Type::Varint });
830        assert!(pb.read_varint::<bool>());
831        // tag 9
832        assert_eq!(pb.read_field(), Field { tag: 9, r#type: Type::Varint });
833        assert!(!pb.read_varint::<bool>());
834
835        // enum
836        // tag 10
837        assert_eq!(pb.read_field(), Field { tag: 10, r#type: Type::Varint });
838        assert_eq!(pb.read_varint::<TestEnum>(), TestEnum::B);
839        // tag 11
840        assert_eq!(pb.read_field(), Field { tag: 11, r#type: Type::Varint });
841        assert_eq!(pb.read_varint::<TestEnum>(), TestEnum::A);
842        // tag 12
843        assert_eq!(pb.read_field(), Field { tag: 12, r#type: Type::Varint });
844        assert_eq!(pb.read_varint::<TestEnum>(), TestEnum::C);
845
846        // float
847        // tag 13
848        assert_eq!(pb.read_field(), Field { tag: 13, r#type: Type::Varint });
849        assert_eq!(pb.read_varint::<f32>(), core::f32::consts::PI);
850        // tag 14
851        assert_eq!(pb.read_field(), Field { tag: 14, r#type: Type::Varint });
852        assert_eq!(pb.read_varint::<f64>(), -core::f64::consts::PI);
853    }
854
855    #[test]
856    fn test_varint_field_2() {
857        let mut pb = Protobuf::new();
858        pb.write_varint_field(1, 5_u8);
859        pb.write_varint_field(2, 5_u16);
860        pb.write_varint_field(3, 5_u32);
861        pb.write_varint_field(4, 5_u64);
862        pb.write_varint_field(5, 5_usize);
863        pb.write_varint_field(6, -5_isize);
864
865        let bytes = pb.take();
866        let mut pb: Protobuf = bytes.into();
867
868        assert_eq!(pb.read_field(), Field { tag: 1, r#type: Type::Varint });
869        assert_eq!(pb.read_varint::<u8>(), 5);
870        assert_eq!(pb.read_field(), Field { tag: 2, r#type: Type::Varint });
871        assert_eq!(pb.read_varint::<u16>(), 5);
872        assert_eq!(pb.read_field(), Field { tag: 3, r#type: Type::Varint });
873        assert_eq!(pb.read_varint::<u32>(), 5);
874        assert_eq!(pb.read_field(), Field { tag: 4, r#type: Type::Varint });
875        assert_eq!(pb.read_varint::<u64>(), 5);
876        assert_eq!(pb.read_field(), Field { tag: 5, r#type: Type::Varint });
877        assert_eq!(pb.read_varint::<usize>(), 5);
878        assert_eq!(pb.read_field(), Field { tag: 6, r#type: Type::Varint });
879        assert_eq!(pb.read_varint::<isize>(), -5);
880    }
881
882    #[test]
883    fn test_s_varint_field() {
884        let mut pb = Protobuf::new();
885        pb.write_s_varint_field(1, 5_i8);
886        pb.write_s_varint_field(2, 5_i16);
887        pb.write_s_varint_field(3, 5_i32);
888        pb.write_s_varint_field(4, 5_i64);
889        pb.write_s_varint_field(5, -5_i8);
890        pb.write_s_varint_field(6, -5_i16);
891        pb.write_s_varint_field(7, -5_i32);
892        pb.write_s_varint_field(8, -5_i64);
893
894        let bytes = pb.take();
895        let mut pb = Protobuf::from_input(bytes);
896
897        assert_eq!(pb.read_field(), Field { tag: 1, r#type: Type::Varint });
898        assert_eq!(pb.read_s_varint::<i8>(), 5);
899        assert_eq!(pb.read_field(), Field { tag: 2, r#type: Type::Varint });
900        assert_eq!(pb.read_s_varint::<i16>(), 5);
901        assert_eq!(pb.read_field(), Field { tag: 3, r#type: Type::Varint });
902        assert_eq!(pb.read_s_varint::<i32>(), 5);
903        assert_eq!(pb.read_field(), Field { tag: 4, r#type: Type::Varint });
904        assert_eq!(pb.read_s_varint::<i64>(), 5);
905        assert_eq!(pb.read_field(), Field { tag: 5, r#type: Type::Varint });
906        assert_eq!(pb.read_s_varint::<i8>(), -5);
907        assert_eq!(pb.read_field(), Field { tag: 6, r#type: Type::Varint });
908        assert_eq!(pb.read_s_varint::<i16>(), -5);
909        assert_eq!(pb.read_field(), Field { tag: 7, r#type: Type::Varint });
910        assert_eq!(pb.read_s_varint::<i32>(), -5);
911        assert_eq!(pb.read_field(), Field { tag: 8, r#type: Type::Varint });
912        assert_eq!(pb.read_s_varint::<i64>(), -5);
913    }
914
915    #[test]
916    fn test_fixed() {
917        let mut pb = Protobuf::new();
918        pb.write_fixed_field(1, 5_u32);
919        pb.write_fixed_field(2, -5_i32);
920        pb.write_fixed_field(3, 5.5_f32);
921        pb.write_fixed_field(4, 5_u64);
922        pb.write_fixed_field(5, -5_i64);
923        pb.write_fixed_field(6, 5.5_f64);
924
925        let bytes = pb.take();
926        let mut pb = Protobuf::from_input(bytes);
927
928        assert_eq!(pb.read_field(), Field { tag: 1, r#type: Type::Fixed32 });
929        assert_eq!(pb.read_fixed::<u32>(), 5);
930        assert_eq!(pb.read_field(), Field { tag: 2, r#type: Type::Fixed32 });
931        assert_eq!(pb.read_fixed::<i32>(), -5);
932        assert_eq!(pb.read_field(), Field { tag: 3, r#type: Type::Fixed32 });
933        assert_eq!(pb.read_fixed::<f32>(), 5.5);
934        assert_eq!(pb.read_field(), Field { tag: 4, r#type: Type::Fixed64 });
935        assert_eq!(pb.read_fixed::<u64>(), 5);
936        assert_eq!(pb.read_field(), Field { tag: 5, r#type: Type::Fixed64 });
937        assert_eq!(pb.read_fixed::<i64>(), -5);
938        assert_eq!(pb.read_field(), Field { tag: 6, r#type: Type::Fixed64 });
939        assert_eq!(pb.read_fixed::<f64>(), 5.5);
940    }
941
942    #[test]
943    #[should_panic(expected = "Invalid fixed type")]
944    fn test_fixed_panic() {
945        let mut pb = Protobuf::new();
946        pb.write_fixed_field(1, 1_u8);
947    }
948
949    #[test]
950    fn test_string() {
951        let mut pb = Protobuf::new();
952        pb.write_string_field(1, "hello");
953        pb.write_string_field(2, "world");
954
955        let bytes = pb.take();
956        let mut pb = Protobuf::from_input(bytes);
957
958        assert_eq!(pb.read_field(), Field { tag: 1, r#type: Type::Bytes });
959        assert_eq!(pb.read_string(), "hello");
960        assert_eq!(pb.read_field(), Field { tag: 2, r#type: Type::Bytes });
961        assert_eq!(pb.read_string(), "world");
962    }
963
964    #[test]
965    fn test_bytes() {
966        let mut pb = Protobuf::new();
967        pb.write_bytes_field(1, &[1, 2, 3]);
968        pb.write_bytes_field(2, &[4, 5, 6]);
969
970        let bytes = pb.take();
971        let mut pb = Protobuf::from_input(bytes);
972
973        assert_eq!(pb.read_field(), Field { tag: 1, r#type: Type::Bytes });
974        assert_eq!(pb.read_bytes(), &[1, 2, 3]);
975        assert_eq!(pb.read_field(), Field { tag: 2, r#type: Type::Bytes });
976        assert_eq!(pb.read_bytes(), &[4, 5, 6]);
977    }
978
979    #[test]
980    fn test_write_field() {
981        let mut pb = Protobuf::new();
982        pb.write_field(1, Type::Varint);
983        pb.write_field(2, Type::None);
984
985        let bytes = pb.take();
986        let mut pb = Protobuf::from_input(bytes);
987
988        assert_eq!(pb.read_field(), Field { tag: 1, r#type: Type::Varint });
989        assert_eq!(pb.read_field(), Field { tag: 2, r#type: Type::None });
990    }
991
992    #[test]
993    fn test_set_pos() {
994        let mut pb = Protobuf::new();
995        pb.write_varint_field(1, 5);
996        pb.write_varint_field(2, 5);
997        pb.write_varint_field(3, 5);
998
999        let bytes = pb.take();
1000        let mut pb = Protobuf::from_input(bytes);
1001
1002        pb.set_pos(2);
1003        assert_eq!(pb.read_field(), Field { tag: 2, r#type: Type::Varint });
1004        assert_eq!(pb.read_varint::<u8>(), 5);
1005        assert_eq!(pb.read_field(), Field { tag: 3, r#type: Type::Varint });
1006        assert_eq!(pb.read_varint::<u8>(), 5);
1007    }
1008
1009    #[test]
1010    fn test_skip() {
1011        let mut pb = Protobuf::new();
1012        pb.write_varint_field(1, 5_u8);
1013        pb.write_fixed_field(2, -5_i32);
1014        pb.write_fixed_field(3, 5.5_f64);
1015        pb.write_packed_varint::<u16>(4, &[1, 2, 3, 4, 5]);
1016        pb.write_field(5, Type::None);
1017        pb.write_varint_field(6, false);
1018
1019        let bytes = pb.take();
1020        let mut pb = Protobuf::from_input(bytes);
1021
1022        let mut field = pb.read_field();
1023        pb.skip(field.r#type); // skip 1 Type::Varint
1024        field = pb.read_field();
1025        pb.skip(field.r#type); // skip 2 Type::Fixed32
1026        field = pb.read_field();
1027        pb.skip(field.r#type); // skip 3 Type::Fixed64
1028        field = pb.read_field();
1029        pb.skip(field.r#type); // skip 4 Type::Bytes
1030        field = pb.read_field();
1031        pb.skip(field.r#type); // skip 5 Type::None
1032        assert_eq!(pb.read_field(), Field { tag: 6, r#type: Type::Varint });
1033    }
1034
1035    #[test]
1036    fn test_packed_and_s_packed() {
1037        let mut pb = Protobuf::new();
1038        pb.write_packed_varint::<u16>(1, &[1, 2, 3]);
1039        pb.write_packed_varint::<f32>(2, &[4.4, 5.5, 6.6]);
1040        pb.write_packed_s_varint(3, &[-1, -2, -3]);
1041
1042        let bytes = pb.take();
1043        let mut pb = Protobuf::from_input(bytes);
1044
1045        assert_eq!(pb.read_field(), Field { tag: 1, r#type: Type::Bytes });
1046        assert_eq!(pb.read_packed::<u16>(), vec![1, 2, 3]);
1047        assert_eq!(pb.read_field(), Field { tag: 2, r#type: Type::Bytes });
1048        assert_eq!(pb.read_packed::<f32>(), vec![4.4, 5.5, 6.6]);
1049        assert_eq!(pb.read_field(), Field { tag: 3, r#type: Type::Bytes });
1050        assert_eq!(pb.read_s_packed::<i32>(), vec![-1, -2, -3]);
1051    }
1052
1053    #[test]
1054    fn test_message() {
1055        #[derive(Debug, PartialEq, Default)]
1056        struct TestMessage {
1057            a: i32,
1058            b: String,
1059        }
1060        impl TestMessage {
1061            fn new(a: i32, b: &str) -> Self {
1062                TestMessage { a, b: b.into() }
1063            }
1064        }
1065        impl ProtoWrite for TestMessage {
1066            fn write(&self, pb: &mut Protobuf) {
1067                pb.write_varint_field::<u64>(1, self.a as u64);
1068                pb.write_string_field(2, &self.b);
1069            }
1070        }
1071        impl ProtoRead for TestMessage {
1072            fn read(&mut self, tag: u64, pb: &mut Protobuf) {
1073                match tag {
1074                    1 => self.a = pb.read_varint(),
1075                    2 => self.b = pb.read_string(),
1076                    _ => panic!("Invalid tag"),
1077                }
1078            }
1079        }
1080
1081        let mut pb = Protobuf::new();
1082        let msg = TestMessage::new(1, "hello");
1083        pb.write_message(1, &msg);
1084
1085        let bytes = pb.take();
1086        let mut pb = Protobuf::from_input(bytes);
1087
1088        // first read in the field for the message
1089        let field = pb.read_field();
1090        assert_eq!(field, Field { tag: 1, r#type: Type::Bytes });
1091
1092        let mut msg = TestMessage::default();
1093        pb.read_message(&mut msg);
1094        assert_eq!(msg.a, 1);
1095        assert_eq!(msg.b, "hello");
1096    }
1097
1098    #[test]
1099    fn test_message_with_skip() {
1100        #[derive(Debug, PartialEq, Default)]
1101        struct TestMessage {
1102            a: i32,
1103            b: String,
1104        }
1105        impl TestMessage {
1106            fn new(a: i32, b: &str) -> Self {
1107                TestMessage { a, b: b.into() }
1108            }
1109        }
1110        impl ProtoWrite for TestMessage {
1111            fn write(&self, pb: &mut Protobuf) {
1112                pb.write_varint_field::<u64>(1, self.a as u64);
1113                pb.write_string_field(2, &self.b);
1114            }
1115        }
1116        impl ProtoRead for TestMessage {
1117            fn read(&mut self, tag: u64, pb: &mut Protobuf) {
1118                if tag == 2 {
1119                    self.b = pb.read_string()
1120                }
1121            }
1122        }
1123
1124        let mut pb = Protobuf::new();
1125        let msg = TestMessage::new(1, "hello");
1126        pb.write_message(1, &msg);
1127
1128        let bytes = pb.take();
1129        let mut pb = Protobuf::from_input(bytes);
1130
1131        // first read in the field for the message
1132        let field = pb.read_field();
1133        assert_eq!(field, Field { tag: 1, r#type: Type::Bytes });
1134
1135        let mut msg = TestMessage::default();
1136        pb.read_message(&mut msg);
1137        assert_eq!(msg.a, 0);
1138        assert_eq!(msg.b, "hello");
1139
1140        // case 2: write_fields
1141        let mut pb = Protobuf::new();
1142        let msg = TestMessage::new(2, "world");
1143        pb.write_fields(&msg);
1144
1145        let bytes = pb.take();
1146        assert_eq!(bytes, vec![8, 2, 18, 5, 119, 111, 114, 108, 100]);
1147        let mut pb = Protobuf::from_input(bytes);
1148        let mut msg = TestMessage::default();
1149        pb.read_fields(&mut msg, None);
1150        assert_eq!(msg.a, 0);
1151        assert_eq!(msg.b, "world");
1152    }
1153
1154    #[test]
1155    fn unicode_string() {
1156        let mut pb = Protobuf::new();
1157        pb.write_string("你好");
1158
1159        let bytes = pb.take();
1160        let mut pb = Protobuf::from_input(bytes);
1161
1162        assert_eq!(pb.read_string(), "你好");
1163    }
1164
1165    #[test]
1166    fn write_float() {
1167        let mut pb = Protobuf::new();
1168        pb.write_varint(5.5_f32);
1169
1170        let bytes = pb.take();
1171        assert_eq!(bytes, vec![128, 128, 192, 133, 4]);
1172
1173        let mut pb2 = Protobuf::new();
1174        pb2.write_varint(30994030.23423423_f64);
1175
1176        let bytes2 = pb2.take();
1177        assert_eq!(bytes2, vec![228, 216, 253, 157, 238, 220, 227, 190, 65]);
1178    }
1179
1180    #[test]
1181    fn is_empty() {
1182        let mut pb = Protobuf::new();
1183        assert!(pb.is_empty());
1184        pb.write_varint(5.5_f32);
1185        assert!(!pb.is_empty());
1186    }
1187
1188    #[test]
1189    fn get_pos() {
1190        let mut pb = Protobuf::new();
1191        pb.write_varint(5.5_f32);
1192
1193        let bytes = pb.take();
1194        assert_eq!(bytes, vec![128, 128, 192, 133, 4]);
1195
1196        let mut pb: Protobuf = bytes.into();
1197        let data = pb.read_varint::<f32>();
1198        assert_eq!(data, 5.5_f32);
1199
1200        assert_eq!(pb.get_pos(), 5);
1201    }
1202
1203    #[test]
1204    fn bug_test() {
1205        let mut pb = Protobuf::new();
1206        pb.write_bytes_field(1, &[127, 55, 192, 128, 0, 0, 128, 182, 11, 129, 108, 22]);
1207
1208        let bytes = pb.take();
1209        let mut pb = Protobuf::from_input(bytes);
1210
1211        let _field = pb.read_field();
1212        assert_eq!(pb.read_bytes(), &[127, 55, 192, 128, 0, 0, 128, 182, 11, 129, 108, 22]);
1213    }
1214
1215    #[test]
1216    fn bug_test_packed() {
1217        let mut pb = Protobuf::new();
1218        let bytes: Vec<u8> = vec![127, 55, 192, 128, 0, 0, 128, 182, 11, 129, 108, 22];
1219        pb.write_packed_varint::<u8>(1, &bytes);
1220
1221        let bytes = pb.take();
1222        let mut pb = Protobuf::from_input(bytes);
1223
1224        let _field = pb.read_field();
1225        assert_eq!(pb.read_packed::<u8>(), &[127, 55, 192, 128, 0, 0, 128, 182, 11, 129, 108, 22]);
1226    }
1227
1228    #[test]
1229    fn test_bug_128() {
1230        let mut pb = Protobuf::new();
1231        pb.write_varint::<u8>(127);
1232        pb.write_varint(55);
1233        pb.write_varint(192);
1234        let bytes = pb.take();
1235        let mut pb = Protobuf::from_input(bytes);
1236        assert_eq!(pb.read_varint::<u8>(), 127);
1237        assert_eq!(pb.read_varint::<u8>(), 55);
1238    }
1239}