usage_monitor_cli/provider/
proto.rs1pub const WIRE_VARINT: u8 = 0;
9pub const WIRE_FIXED64: u8 = 1;
10pub const WIRE_LEN: u8 = 2;
11pub const WIRE_FIXED32: u8 = 5;
12
13pub struct Reader<'a> {
15 data: &'a [u8],
16 pos: usize,
17}
18
19impl<'a> Reader<'a> {
20 pub fn new(data: &'a [u8]) -> Self {
21 Self { data, pos: 0 }
22 }
23
24 pub fn done(&self) -> bool {
25 self.pos >= self.data.len()
26 }
27
28 pub fn read_varint(&mut self) -> Option<u64> {
30 let mut result: u64 = 0;
31 let mut shift = 0;
32 loop {
33 let byte = *self.data.get(self.pos)?;
34 self.pos += 1;
35 result |= ((byte & 0x7f) as u64) << shift;
36 if byte & 0x80 == 0 {
37 return Some(result);
38 }
39 shift += 7;
40 if shift >= 64 {
41 return None;
42 }
43 }
44 }
45
46 pub fn next_key(&mut self) -> Option<(u32, u8)> {
48 let key = self.read_varint()?;
49 let field = (key >> 3) as u32;
50 let wire = (key & 0x07) as u8;
51 if field == 0 {
52 return None;
53 }
54 Some((field, wire))
55 }
56
57 pub fn read_len(&mut self) -> Option<&'a [u8]> {
59 let len = self.read_varint()? as usize;
60 let end = self.pos.checked_add(len)?;
61 if end > self.data.len() {
62 return None;
63 }
64 let slice = &self.data[self.pos..end];
65 self.pos = end;
66 Some(slice)
67 }
68
69 pub fn read_fixed32(&mut self) -> Option<u32> {
70 let end = self.pos.checked_add(4)?;
71 if end > self.data.len() {
72 return None;
73 }
74 let b = &self.data[self.pos..end];
75 self.pos = end;
76 Some(u32::from_le_bytes([b[0], b[1], b[2], b[3]]))
77 }
78
79 pub fn read_fixed64(&mut self) -> Option<u64> {
80 let end = self.pos.checked_add(8)?;
81 if end > self.data.len() {
82 return None;
83 }
84 let b = &self.data[self.pos..end];
85 self.pos = end;
86 Some(u64::from_le_bytes([
87 b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7],
88 ]))
89 }
90
91 pub fn skip(&mut self, wire: u8) -> Option<()> {
94 match wire {
95 WIRE_VARINT => self.read_varint().map(|_| ()),
96 WIRE_FIXED64 => self.read_fixed64().map(|_| ()),
97 WIRE_LEN => self.read_len().map(|_| ()),
98 WIRE_FIXED32 => self.read_fixed32().map(|_| ()),
99 _ => None,
100 }
101 }
102}
103
104pub fn encode_varint(mut value: u64, out: &mut Vec<u8>) {
106 while value >= 0x80 {
107 out.push(((value & 0x7f) | 0x80) as u8);
108 value >>= 7;
109 }
110 out.push(value as u8);
111}
112
113pub fn encode_key(field: u32, wire: u8, out: &mut Vec<u8>) {
115 encode_varint(((field as u64) << 3) | wire as u64, out);
116}
117
118pub fn encode_string_field(field: u32, value: &str, out: &mut Vec<u8>) {
120 encode_key(field, WIRE_LEN, out);
121 encode_varint(value.len() as u64, out);
122 out.extend_from_slice(value.as_bytes());
123}
124
125pub fn encode_varint_field(field: u32, value: u64, out: &mut Vec<u8>) {
127 encode_key(field, WIRE_VARINT, out);
128 encode_varint(value, out);
129}
130
131#[cfg(test)]
132mod tests {
133 use super::*;
134
135 #[test]
136 fn test_varint_roundtrip() {
137 for v in [0u64, 1, 127, 128, 300, 16384, u32::MAX as u64, u64::MAX] {
138 let mut buf = Vec::new();
139 encode_varint(v, &mut buf);
140 let mut r = Reader::new(&buf);
141 assert_eq!(r.read_varint(), Some(v));
142 assert!(r.done());
143 }
144 }
145
146 #[test]
147 fn test_field_encode_decode() {
148 let mut buf = Vec::new();
149 encode_string_field(1, "tok", &mut buf);
150 encode_varint_field(2, 1, &mut buf);
151
152 let mut r = Reader::new(&buf);
153 assert_eq!(r.next_key(), Some((1, WIRE_LEN)));
154 assert_eq!(r.read_len(), Some(&b"tok"[..]));
155 assert_eq!(r.next_key(), Some((2, WIRE_VARINT)));
156 assert_eq!(r.read_varint(), Some(1));
157 assert!(r.done());
158 }
159
160 #[test]
161 fn test_skip() {
162 let mut buf = Vec::new();
163 encode_varint_field(1, 42, &mut buf);
164 encode_string_field(2, "keep", &mut buf);
165 let mut r = Reader::new(&buf);
166 let (f, w) = r.next_key().unwrap();
167 assert_eq!(f, 1);
168 r.skip(w).unwrap();
169 assert_eq!(r.next_key(), Some((2, WIRE_LEN)));
170 assert_eq!(r.read_len(), Some(&b"keep"[..]));
171 }
172
173 #[test]
174 fn test_truncated_varint_is_none() {
175 let mut r = Reader::new(&[0x80]); assert_eq!(r.read_varint(), None);
177 }
178
179 #[test]
180 fn test_read_len_out_of_bounds() {
181 let mut r = Reader::new(&[0x0a, b'h', b'i']);
183 let (_f, _w) = r.next_key().unwrap();
184 assert_eq!(r.read_len(), None);
185 }
186
187 #[test]
188 fn test_fixed32() {
189 let bytes = 3.5f32.to_bits().to_le_bytes();
190 let mut r = Reader::new(&bytes);
191 assert_eq!(r.read_fixed32().map(f32::from_bits), Some(3.5));
192 }
193}