1pub fn encode_to_vec(mut n: u128, v: &mut Vec<u8>) {
7 while n >> 7 > 0 {
8 v.push(n.to_le_bytes()[0] | 0b1000_0000);
9 n >>= 7;
10 }
11 v.push(n.to_le_bytes()[0]);
12}
13
14pub fn decode(buffer: &[u8]) -> Result<(u128, usize), Error> {
16 let mut n = 0u128;
17
18 for (i, &byte) in buffer.iter().enumerate() {
19 if i > 18 {
20 return Err(Error::Overlong);
21 }
22
23 let value = u128::from(byte) & 0b0111_1111;
24
25 if i == 18 && value & 0b0111_1100 != 0 {
26 return Err(Error::Overflow);
27 }
28
29 n |= value << (7 * i);
30
31 if byte & 0b1000_0000 == 0 {
32 return Ok((n, i + 1));
33 }
34 }
35
36 Err(Error::Unterminated)
37}
38
39pub fn encode(n: u128) -> Vec<u8> {
41 let mut v = Vec::new();
42 encode_to_vec(n, &mut v);
43 v
44}
45
46#[derive(PartialEq, Debug)]
48pub enum Error {
49 Overlong,
51 Overflow,
53 Unterminated,
55}
56
57impl std::fmt::Display for Error {
58 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
59 match self {
60 Self::Overlong => write!(f, "too long"),
61 Self::Overflow => write!(f, "overflow"),
62 Self::Unterminated => write!(f, "unterminated"),
63 }
64 }
65}
66
67impl std::error::Error for Error {}
68
69#[cfg(test)]
70mod tests {
71 use super::*;
72
73 #[test]
74 fn zero_round_trips_successfully() {
75 let n = 0;
76 let encoded = encode(n);
77 let (decoded, length) = decode(&encoded).unwrap();
78 assert_eq!(decoded, n);
79 assert_eq!(length, encoded.len());
80 }
81
82 #[test]
83 fn u128_max_round_trips_successfully() {
84 let n = u128::MAX;
85 let encoded = encode(n);
86 let (decoded, length) = decode(&encoded).unwrap();
87 assert_eq!(decoded, n);
88 assert_eq!(length, encoded.len());
89 }
90
91 #[test]
92 fn powers_of_two_round_trip_successfully() {
93 for i in 0..128 {
94 let n = 1 << i;
95 let encoded = encode(n);
96 let (decoded, length) = decode(&encoded).unwrap();
97 assert_eq!(decoded, n);
98 assert_eq!(length, encoded.len());
99 }
100 }
101
102 #[test]
103 fn alternating_bit_strings_round_trip_successfully() {
104 let mut n = 0;
105
106 for i in 0..129 {
107 n = (n << 1) | (i % 2);
108 let encoded = encode(n);
109 let (decoded, length) = decode(&encoded).unwrap();
110 assert_eq!(decoded, n);
111 assert_eq!(length, encoded.len());
112 }
113 }
114
115 #[test]
116 fn varints_may_not_be_longer_than_19_bytes() {
117 const VALID: [u8; 19] = [
118 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
119 128, 0,
120 ];
121
122 const INVALID: [u8; 20] = [
123 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
124 128, 128, 0,
125 ];
126
127 assert_eq!(decode(&VALID), Ok((0, 19)));
128 assert_eq!(decode(&INVALID), Err(Error::Overlong));
129 }
130
131 #[test]
132 fn varints_may_not_overflow_u128() {
133 assert_eq!(
134 decode(&[
135 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
136 128, 128, 64,
137 ]),
138 Err(Error::Overflow)
139 );
140 assert_eq!(
141 decode(&[
142 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
143 128, 128, 32,
144 ]),
145 Err(Error::Overflow)
146 );
147 assert_eq!(
148 decode(&[
149 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
150 128, 128, 16,
151 ]),
152 Err(Error::Overflow)
153 );
154 assert_eq!(
155 decode(&[
156 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
157 128, 128, 8,
158 ]),
159 Err(Error::Overflow)
160 );
161 assert_eq!(
162 decode(&[
163 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
164 128, 128, 4,
165 ]),
166 Err(Error::Overflow)
167 );
168 assert_eq!(
169 decode(&[
170 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
171 128, 128, 2,
172 ]),
173 Ok((2u128.pow(127), 19))
174 );
175 }
176
177 #[test]
178 fn varints_must_be_terminated() {
179 assert_eq!(decode(&[128]), Err(Error::Unterminated));
180 }
181}