1use crate::error::DecodeError;
2
3pub fn encode(buf: &mut Vec<u8>, mut value: u64) {
5 loop {
6 let mut byte = (value & 0x7F) as u8;
7 value >>= 7;
8 if value != 0 {
9 byte |= 0x80;
10 }
11 buf.push(byte);
12 if value == 0 {
13 break;
14 }
15 }
16}
17
18pub fn decode(data: &[u8], max_bytes: u8) -> Result<(u64, usize), DecodeError> {
25 let mut result: u64 = 0;
26 let mut shift: u32 = 0;
27
28 for (i, &byte) in data.iter().enumerate() {
29 if i >= max_bytes as usize {
30 return Err(DecodeError::InvalidVarint);
31 }
32 result |= u64::from(byte & 0x7F) << shift;
33 shift += 7;
34
35 if byte & 0x80 == 0 {
36 if i > 0 && byte == 0 {
38 return Err(DecodeError::InvalidVarint);
39 }
40 return Ok((result, i + 1));
41 }
42 }
43 Err(DecodeError::UnexpectedEof)
44}
45
46#[cfg(test)]
47mod tests {
48 use super::*;
49
50 #[test]
51 fn encode_zero() {
52 let mut b = Vec::new();
53 encode(&mut b, 0);
54 assert_eq!(b, [0x00]);
55 }
56
57 #[test]
58 fn encode_127() {
59 let mut b = Vec::new();
60 encode(&mut b, 127);
61 assert_eq!(b, [0x7F]);
62 }
63
64 #[test]
65 fn encode_128() {
66 let mut b = Vec::new();
67 encode(&mut b, 128);
68 assert_eq!(b, [0x80, 0x01]);
69 }
70
71 #[test]
72 fn encode_300() {
73 let mut b = Vec::new();
74 encode(&mut b, 300);
75 assert_eq!(b, [0xAC, 0x02]);
76 }
77
78 #[test]
79 fn round_trip_max_u64() {
80 let mut buf = Vec::new();
81 encode(&mut buf, u64::MAX);
82 let (val, consumed) = decode(&buf, 10).unwrap();
83 assert_eq!(val, u64::MAX);
84 assert_eq!(consumed, 10);
85 }
86
87 #[test]
88 fn decode_max_4_bytes_limit() {
89 let mut buf = Vec::new();
90 encode(&mut buf, (1 << 28) - 1);
91 assert!(buf.len() <= 4);
92 let (val, _) = decode(&buf, 4).unwrap();
93 assert_eq!(val, (1 << 28) - 1);
94 }
95
96 #[test]
97 fn decode_exceeds_max_bytes() {
98 let mut buf = Vec::new();
99 encode(&mut buf, 1 << 28);
100 assert!(decode(&buf, 4).is_err());
101 }
102
103 #[test]
104 fn reject_overlong_encoding() {
105 let buf = [0x80, 0x00];
106 assert!(decode(&buf, 10).is_err());
107 }
108}