protobuf_to_json/
varint.rs1pub const MSB: u8 = 0b1000_0000;
6const DROP_MSB: u8 = 0b0111_1111;
9
10pub fn decode_var(src: &mut &[u8]) -> Result<u64, ()> {
12 let mut result: u64 = 0;
13 let mut shift = 0;
14
15 let mut success = false;
16 for b in src.iter() {
17 let msb_dropped = b & DROP_MSB;
18 result |= (msb_dropped as u64) << shift;
19 shift += 7;
20
21 if b & MSB == 0 || shift > (9 * 7) {
22 success = b & MSB == 0;
23 break;
24 }
25 }
26
27 if success {
28 *src = &src[shift / 7..];
29 Ok(result)
30 } else {
31 Err(())
32 }
33}
34
35#[cfg(test)]
36mod tests {
37 use super::*;
38
39 #[test]
40 fn test_decode_max_u64() {
41 let max_vec_encoded = vec![0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01];
42 assert_eq!(
43 decode_var(&mut max_vec_encoded.as_slice()).unwrap(),
44 u64::max_value()
45 );
46 }
47
48 #[test]
49 fn test_decode_zero() {
50 let zero_encoded = vec![0x00];
51 assert_eq!(decode_var(&mut zero_encoded.as_slice()).unwrap(), 0);
52 }
53
54 #[test]
55 fn test_decode_one() {
56 let one_encoded = vec![0x01];
57 assert_eq!(decode_var(&mut one_encoded.as_slice()).unwrap(), 1);
58 }
59
60 #[test]
61 fn test_decode_large_number() {
62 let large_number_encoded = vec![0xAC, 0x02];
63 assert_eq!(
64 decode_var(&mut large_number_encoded.as_slice()).unwrap(),
65 300
66 );
67 }
68
69 #[test]
70 fn test_decode_incomplete_sequence() {
71 let incomplete_encoded = vec![0xFF, 0xFF, 0xFF];
72 assert!(decode_var(&mut incomplete_encoded.as_slice()).is_err());
73 }
74
75 #[test]
76 fn test_decode_single_byte_with_msb() {
77 let single_byte_with_msb = vec![0x80];
78 assert!(decode_var(&mut single_byte_with_msb.as_slice()).is_err());
79 }
80
81 #[test]
82 fn test_decode_empty_input() {
83 let empty_input: Vec<u8> = vec![];
84 assert!(decode_var(&mut empty_input.as_slice()).is_err());
85 }
86}