protobuf_to_json/
message.rs

1use crate::decode_var;
2
3/// Protocol buffer message.
4#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
5pub struct Message<'a> {
6    /// Decoded fields.
7    pub fields: Vec<Field<'a>>,
8
9    /// Garbage data at the end of the message.
10    ///
11    /// As opposed to an `UnknownValue::Invalid`, the garbage data did not have a valid field
12    /// number and for that reason cannot be placed into the `fields` vector.
13    pub garbage: Option<&'a [u8]>,
14}
15
16/// Decoded protocol buffer field.
17///
18#[derive(Debug, PartialEq, Clone, Eq, Hash)]
19pub struct Field<'a> {
20    /// Field number.
21    pub number: u64,
22
23    /// Decoded value.
24    pub value: FieldValue<'a>,
25}
26
27/// Decoded protocol buffer value.
28///
29///
30/// The wire type allows the decoder to tell how large an unknown value is. This allows the
31/// unknown value to be skipped and decoding can continue from the next value.
32///
33#[derive(Debug, PartialEq, Clone, Eq, Hash)]
34pub enum FieldValue<'a> {
35    /// Varint (wire type = 0).
36    Varint(u128),
37
38    /// 64-bit value (wire type = 1).
39    Fixed64(u64),
40
41    /// Length-delimited value (wire type = 2).
42    LengthDelimited(&'a [u8]),
43
44    /// 32-bit value (wire type = 5).
45    Fixed32(u32),
46
47    /// Invalid value.
48    ///
49    /// Invalid value is a value for which the wire type wasn't valid. Encountering invalid wire
50    /// type will result in the remaining bytes to be consumed from the current variable length
51    /// stream as it is imposible to tell how large such invalid value is.
52    ///
53    /// The decoding will continue after the current variable length value.
54    Invalid(u8, &'a [u8]),
55
56    /// Value which was incomplete due to missing bytes in the payload.
57    Incomplete(WireType, &'a [u8]),
58}
59
60impl<'a> FieldValue<'a> {
61    pub fn decode(data: &mut &'a [u8], wire_type: WireType) -> Self {
62        match wire_type {
63            WireType::Varint => match decode_var(data) {
64                Ok(v) => FieldValue::Varint(v as u128),
65                Err(_) => FieldValue::Incomplete(wire_type, *data),
66            },
67            WireType::Fixed64 => {
68                if data.len() < 8 {
69                    FieldValue::Incomplete(wire_type, *data)
70                } else {
71                    let (num_bytes, rest) = data.split_at(8);
72                    *data = rest;
73                    let mut arr = [0u8; 8];
74                    arr.copy_from_slice(num_bytes);
75                    FieldValue::Fixed64(u64::from_le_bytes(arr))
76                }
77            }
78            WireType::LengthDelimited => match decode_var(data) {
79                Ok(len) => {
80                    let len = len as usize;
81                    if data.len() < len {
82                        FieldValue::Incomplete(wire_type, *data)
83                    } else {
84                        let (bytes, rest) = data.split_at(len);
85                        *data = rest;
86                        FieldValue::LengthDelimited(bytes)
87                    }
88                }
89                Err(_) => FieldValue::Incomplete(wire_type, *data),
90            },
91            WireType::Fixed32 => {
92                if data.len() < 4 {
93                    FieldValue::Incomplete(wire_type, *data)
94                } else {
95                    let (num_bytes, rest) = data.split_at(4);
96                    *data = rest;
97                    let mut arr = [0u8; 4];
98                    arr.copy_from_slice(num_bytes);
99                    FieldValue::Fixed32(u32::from_le_bytes(arr))
100                }
101            }
102            WireType::Invalid(wt) => FieldValue::Invalid(wt, *data),
103        }
104    }
105}
106
107/// Protocol buffer wire types.
108#[derive(Debug, PartialEq, Clone, Eq, Copy, Hash)]
109#[repr(u8)]
110pub enum WireType {
111    /// Varint (0)
112    Varint = 0,
113
114    /// 64-bit (1)
115    Fixed64 = 1,
116
117    /// Length-delimited (2)
118    LengthDelimited = 2,
119
120    /// 32-bit (5)
121    Fixed32 = 5,
122
123    /// Invalid wire type
124    Invalid(u8),
125}
126
127impl From<u8> for WireType {
128    fn from(value: u8) -> Self {
129        match value {
130            0 => WireType::Varint,
131            1 => WireType::Fixed64,
132            2 => WireType::LengthDelimited,
133            5 => WireType::Fixed32,
134            other => WireType::Invalid(other),
135        }
136    }
137}