1use crate::{Decode, DecodeError, Encode};
2
3#[derive(Debug, Clone, PartialEq, Eq)]
4pub struct VarI32(pub i32);
5
6impl Encode for VarI32 {
7 fn encode(&self, buf: &mut Vec<u8>) {
8 let mut value = self.0 as u32;
9 loop {
10 let mut byte = (value & 0x7F) as u8;
11 value >>= 7;
12
13 if value != 0 {
14 byte |= 0x80;
15 }
16
17 buf.push(byte);
18
19 if value == 0 {
20 break;
21 }
22 }
23 }
24}
25
26impl Decode for VarI32 {
27 fn decode(buf: &mut &[u8]) -> Result<Self, DecodeError> {
28 let mut value: u32 = 0;
29 let mut shift = 0;
30
31 for _ in 0..5 {
32 if buf.is_empty() {
33 return Err(DecodeError::UnexpectedEof);
34 }
35
36 let byte = buf[0];
37 *buf = &buf[1..];
38
39 value |= ((byte & 0x7F) as u32) << shift;
40
41 if byte & 0x80 == 0 {
42 return Ok(VarI32(value as i32));
43 }
44
45 shift += 7;
46 }
47
48 Err(DecodeError::InvalidVarintLength)
49 }
50}
51
52#[cfg(test)]
53mod tests {
54 use super::*;
55
56 #[test]
57 fn test_vari32_zero() {
58 let value = VarI32(0);
59 let mut buf = Vec::new();
60 value.encode(&mut buf);
61 assert_eq!(buf, vec![0x00]);
62
63 let mut slice = buf.as_slice();
64 let decoded = VarI32::decode(&mut slice).unwrap();
65 assert_eq!(decoded.0, 0);
66 }
67
68 #[test]
69 fn test_vari32_small_positive() {
70 let value = VarI32(127);
71 let mut buf = Vec::new();
72 value.encode(&mut buf);
73 assert_eq!(buf, vec![0x7F]);
74
75 let mut slice = buf.as_slice();
76 let decoded = VarI32::decode(&mut slice).unwrap();
77 assert_eq!(decoded.0, 127);
78 }
79
80 #[test]
81 fn test_vari32_128() {
82 let value = VarI32(128);
83 let mut buf = Vec::new();
84 value.encode(&mut buf);
85 assert_eq!(buf, vec![0x80, 0x01]);
86
87 let mut slice = buf.as_slice();
88 let decoded = VarI32::decode(&mut slice).unwrap();
89 assert_eq!(decoded.0, 128);
90 }
91
92 #[test]
93 fn test_vari32_negative() {
94 let value = VarI32(-1);
95 let mut buf = Vec::new();
96 value.encode(&mut buf);
97
98 let mut slice = buf.as_slice();
99 let decoded = VarI32::decode(&mut slice).unwrap();
100 assert_eq!(decoded.0, -1);
101 }
102
103 #[test]
104 fn test_vari32_max() {
105 let value = VarI32(i32::MAX);
106 let mut buf = Vec::new();
107 value.encode(&mut buf);
108
109 let mut slice = buf.as_slice();
110 let decoded = VarI32::decode(&mut slice).unwrap();
111 assert_eq!(decoded.0, i32::MAX);
112 }
113
114 #[test]
115 fn test_vari32_min() {
116 let value = VarI32(i32::MIN);
117 let mut buf = Vec::new();
118 value.encode(&mut buf);
119
120 let mut slice = buf.as_slice();
121 let decoded = VarI32::decode(&mut slice).unwrap();
122 assert_eq!(decoded.0, i32::MIN);
123 }
124
125 #[test]
126 fn test_vari32_truncated() {
127 let mut slice = &[0x80][..];
128 let result = VarI32::decode(&mut slice);
129 assert_eq!(result, Err(DecodeError::UnexpectedEof));
130 }
131
132 #[test]
133 fn test_vari32_too_long() {
134 let bytes = vec![0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF];
135 let mut slice = bytes.as_slice();
136 let result = VarI32::decode(&mut slice);
137 assert_eq!(result, Err(DecodeError::InvalidVarintLength));
138 }
139
140 #[test]
141 fn test_vari32_exact_bytes_zero() {
142 let value = VarI32(0);
143 let mut buf = Vec::new();
144 value.encode(&mut buf);
145 assert_eq!(buf, vec![0x00]);
146 }
147
148 #[test]
149 fn test_vari32_exact_bytes_one() {
150 let value = VarI32(1);
151 let mut buf = Vec::new();
152 value.encode(&mut buf);
153 assert_eq!(buf, vec![0x01]);
154 }
155
156 #[test]
157 fn test_vari32_exact_bytes_127() {
158 let value = VarI32(127);
159 let mut buf = Vec::new();
160 value.encode(&mut buf);
161 assert_eq!(buf, vec![0x7F]);
162 }
163
164 #[test]
165 fn test_vari32_exact_bytes_128() {
166 let value = VarI32(128);
167 let mut buf = Vec::new();
168 value.encode(&mut buf);
169 assert_eq!(buf, vec![0x80, 0x01]);
170 }
171
172 #[test]
173 fn test_vari32_exact_bytes_255() {
174 let value = VarI32(255);
175 let mut buf = Vec::new();
176 value.encode(&mut buf);
177 assert_eq!(buf, vec![0xFF, 0x01]);
178 }
179
180 #[test]
181 fn test_vari32_exact_bytes_256() {
182 let value = VarI32(256);
183 let mut buf = Vec::new();
184 value.encode(&mut buf);
185 assert_eq!(buf, vec![0x80, 0x02]);
186 }
187
188 #[test]
189 fn test_vari32_exact_bytes_16383() {
190 let value = VarI32(16383);
191 let mut buf = Vec::new();
192 value.encode(&mut buf);
193 assert_eq!(buf, vec![0xFF, 0x7F]);
194 }
195
196 #[test]
197 fn test_vari32_exact_bytes_16384() {
198 let value = VarI32(16384);
199 let mut buf = Vec::new();
200 value.encode(&mut buf);
201 assert_eq!(buf, vec![0x80, 0x80, 0x01]);
202 }
203
204 #[test]
205 fn test_vari32_negative_exact_bytes() {
206 let value = VarI32(-1);
207 let mut buf = Vec::new();
208 value.encode(&mut buf);
209 assert_eq!(buf, vec![0xFF, 0xFF, 0xFF, 0xFF, 0x0F]);
210 }
211
212 #[test]
213 fn test_vari32_negative_two() {
214 let value = VarI32(-2);
215 let mut buf = Vec::new();
216 value.encode(&mut buf);
217 assert_eq!(buf, vec![0xFE, 0xFF, 0xFF, 0xFF, 0x0F]);
218 }
219
220 #[test]
221 fn test_vari32_negative_128() {
222 let value = VarI32(-128);
223 let mut buf = Vec::new();
224 value.encode(&mut buf);
225 assert_eq!(buf, vec![0x80, 0xFF, 0xFF, 0xFF, 0x0F]);
226 }
227
228 #[test]
229 fn test_vari32_100() {
230 let value = VarI32(100);
231 let mut buf = Vec::new();
232 value.encode(&mut buf);
233 assert_eq!(buf.len(), 1);
234 assert_eq!(buf, vec![100]);
235 }
236
237 #[test]
238 fn test_vari32_1000() {
239 let value = VarI32(1000);
240 let mut buf = Vec::new();
241 value.encode(&mut buf);
242 assert_eq!(buf.len(), 2);
243 assert_eq!(buf, vec![0xE8, 0x07]);
244 }
245
246 #[test]
247 fn test_vari32_serialization_efficiency() {
248 struct TestCase {
249 value: i32,
250 expected_len: usize,
251 }
252
253 let cases = [
254 TestCase {
255 value: 0,
256 expected_len: 1,
257 },
258 TestCase {
259 value: 127,
260 expected_len: 1,
261 },
262 TestCase {
263 value: 128,
264 expected_len: 2,
265 },
266 TestCase {
267 value: 16383,
268 expected_len: 2,
269 },
270 TestCase {
271 value: 16384,
272 expected_len: 3,
273 },
274 TestCase {
275 value: i32::MAX,
276 expected_len: 5,
277 },
278 ];
279
280 for case in &cases {
281 let mut buf = Vec::new();
282 VarI32(case.value).encode(&mut buf);
283 assert_eq!(
284 buf.len(),
285 case.expected_len,
286 "VarI32({}) should encode to {} bytes, got {}",
287 case.value,
288 case.expected_len,
289 buf.len()
290 );
291 }
292 }
293
294 #[test]
295 fn test_vari32_java_compliance_roundtrip() {
296 let test_values = [
297 0,
298 1,
299 127,
300 128,
301 255,
302 256,
303 16383,
304 16384,
305 -1,
306 -2,
307 -128,
308 -32768,
309 i32::MAX,
310 i32::MIN,
311 ];
312
313 for value in &test_values {
314 let vi32 = VarI32(*value);
315 let mut buf = Vec::new();
316 vi32.encode(&mut buf);
317
318 let mut slice = buf.as_slice();
319 let decoded = VarI32::decode(&mut slice).unwrap();
320 assert_eq!(
321 decoded.0, *value,
322 "VarI32 roundtrip failed for value {}",
323 value
324 );
325 assert_eq!(
326 slice.len(),
327 0,
328 "VarI32 decode didn't consume all bytes for value {}",
329 value
330 );
331 }
332 }
333
334 #[test]
335 fn test_vari32_max_bytes_limit() {
336 let mut buf = Vec::new();
337 (i32::MAX).encode(&mut buf);
338 assert!(
339 buf.len() <= 5,
340 "VarI32 should encode to at most 5 bytes, got {}",
341 buf.len()
342 );
343 }
344
345 #[test]
346 fn test_vari32_more_than_five_bytes_rejected() {
347 let bytes = vec![0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01];
348 let mut slice = bytes.as_slice();
349 let result = VarI32::decode(&mut slice);
350 assert!(
351 result.is_err(),
352 "VarI32 with 6 bytes should be rejected like Java's position >= 32 check"
353 );
354 }
355
356 #[test]
357 fn test_vari32_java_segment_and_continue_bits() {
358 let value = VarI32(300);
359 let mut buf = Vec::new();
360 value.encode(&mut buf);
361
362 assert_eq!(buf.len(), 2);
363 assert_eq!(buf[0] & 0x80, 0x80, "First byte should have continue bit");
364 assert_eq!(
365 buf[1] & 0x80,
366 0x00,
367 "Last byte should NOT have continue bit"
368 );
369
370 let segment_bits = 0x7F;
371
372 assert_eq!(
373 buf[0] & segment_bits,
374 300u32 as u8 & segment_bits,
375 "First byte segment bits should match"
376 );
377 }
378
379 #[test]
380 fn test_vari32_java_logic_equivalence() {
381 let test_values = [0, 1, 63, 64, 127, 128, 255, 256, 16383, 16384];
382
383 for &value in &test_values {
384 let vi32 = VarI32(value);
385 let mut buf = Vec::new();
386 vi32.encode(&mut buf);
387
388 assert!(!buf.is_empty(), "VarI32 should encode to at least 1 byte");
389 assert!(buf.len() <= 5, "VarI32 should encode to at most 5 bytes");
390
391 let mut decoded_value = 0u32;
392 for (i, &byte) in buf.iter().enumerate() {
393 decoded_value |= ((byte & 0x7F) as u32) << (i * 7);
394
395 if byte & 0x80 == 0 {
396 assert_eq!(
397 i + 1,
398 buf.len(),
399 "No-continue-bit should be on the last byte"
400 );
401 break;
402 }
403 }
404
405 assert_eq!(
406 decoded_value, value as u32,
407 "Manual decode should match encoded value for {}: bytes = {:?}",
408 value, buf
409 );
410 }
411 }
412}