tempest_core/encoding/
varint.rs1use bytes::{BufMut, BytesMut};
2use integer_encoding::VarInt;
3
4pub fn encode_varint(buf: &mut BytesMut, i: usize) {
6 let varint_size = i.required_space();
8 buf.put_bytes(0, varint_size);
9 let buflen = buf.len();
11 let written = i.encode_var(&mut buf[buflen - varint_size..]);
12 debug_assert_eq!(written, varint_size);
13}
14
15pub fn decode_varint(src: &[u8]) -> Option<(usize, usize)> {
22 usize::decode_var(src)
23}
24
25#[cfg(test)]
26mod tests {
27 use bytes::BytesMut;
28
29 use super::*;
30
31 fn roundtrip(i: usize) -> (usize, usize) {
32 let mut buf = BytesMut::new();
33 encode_varint(&mut buf, i);
34 let (val, bytes_read) = decode_varint(&buf).expect("decode failed");
35 assert_eq!(val, i, "roundtrip failed for {}", i);
36 (val, bytes_read)
37 }
38
39 #[test]
42 fn test_roundtrip_zero() {
43 roundtrip(0);
44 }
45
46 #[test]
47 fn test_roundtrip_one() {
48 roundtrip(1);
49 }
50
51 #[test]
52 fn test_roundtrip_max_one_byte() {
53 roundtrip(127); }
55
56 #[test]
57 fn test_roundtrip_min_two_bytes() {
58 roundtrip(128); }
60
61 #[test]
62 fn test_roundtrip_large_values() {
63 for val in [255, 256, 1024, 65535, 65536, 1 << 20, 1 << 28] {
64 roundtrip(val);
65 }
66 }
67
68 #[test]
69 fn test_roundtrip_usize_max() {
70 roundtrip(usize::MAX);
71 }
72
73 #[test]
76 fn test_single_byte_encoding() {
77 let mut buf = BytesMut::new();
78 encode_varint(&mut buf, 127);
79 assert_eq!(buf.len(), 1, "127 should encode to 1 byte");
80 }
81
82 #[test]
83 fn test_two_byte_encoding() {
84 let mut buf = BytesMut::new();
85 encode_varint(&mut buf, 128);
86 assert_eq!(buf.len(), 2, "128 should encode to 2 bytes");
87 }
88
89 #[test]
90 fn test_zero_encodes_to_one_byte() {
91 let mut buf = BytesMut::new();
92 encode_varint(&mut buf, 0);
93 assert_eq!(buf.len(), 1);
94 }
95
96 #[test]
99 fn test_decode_returns_correct_bytes_read() {
100 let mut buf = BytesMut::new();
101 encode_varint(&mut buf, 128);
102 let (_, bytes_read) = decode_varint(&buf).unwrap();
103 assert_eq!(bytes_read, 2);
104 }
105
106 #[test]
107 fn test_decode_none_on_all_msb_set() {
108 let buf = &[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF];
110 assert!(decode_varint(buf).is_none());
111 }
112
113 #[test]
114 fn test_decode_ignores_trailing_bytes() {
115 let mut buf = BytesMut::new();
117 encode_varint(&mut buf, 42);
118 buf.extend_from_slice(&[0xAB, 0xCD]); let (val, bytes_read) = decode_varint(&buf).unwrap();
120 assert_eq!(val, 42);
121 assert!(bytes_read < buf.len(), "should not consume trailing bytes");
122 }
123
124 #[test]
127 fn test_multiple_varints_sequential() {
128 let values = [0usize, 1, 127, 128, 300, 100_000];
130 let mut buf = BytesMut::new();
131 for &v in &values {
132 encode_varint(&mut buf, v);
133 }
134
135 let mut slice = &buf[..];
136 for &expected in &values {
137 let (val, bytes_read) = decode_varint(slice).unwrap();
138 assert_eq!(val, expected);
139 slice = &slice[bytes_read..];
140 }
141 assert!(slice.is_empty(), "buffer should be fully consumed");
142 }
143}