pbf_core/
lib.rs

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