1use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
2
3#[derive(Debug)]
4pub struct DecodeError(pub &'static str);
5
6#[inline]
7pub fn write_varu32(buf: &mut Vec<u8>, mut value: u32) {
8 while value >= 0x80 {
9 buf.push((value as u8) | 0x80);
10 value >>= 7;
11 }
12 buf.push(value as u8);
13}
14
15#[inline]
16pub fn write_varu64(buf: &mut Vec<u8>, mut value: u64) {
17 while value >= 0x80 {
18 buf.push((value as u8) | 0x80);
19 value >>= 7;
20 }
21 buf.push(value as u8);
22}
23
24#[inline]
25pub fn write_vari32(buf: &mut Vec<u8>, value: i32) {
26 let zigzag = ((value << 1) ^ (value >> 31)) as u32;
27 write_varu32(buf, zigzag);
28}
29
30#[inline]
31pub fn write_vari64(buf: &mut Vec<u8>, value: i64) {
32 let zigzag = ((value << 1) ^ (value >> 63)) as u64;
33 write_varu64(buf, zigzag);
34}
35
36#[inline]
37pub fn read_varu32(bytes: &[u8], pos: &mut usize) -> Result<u32, DecodeError> {
38 let mut result = 0u32;
39 let mut shift = 0u32;
40 while *pos < bytes.len() {
41 let byte = bytes[*pos];
42 *pos += 1;
43 result |= ((byte & 0x7F) as u32) << shift;
44 if byte & 0x80 == 0 {
45 return Ok(result);
46 }
47 shift += 7;
48 if shift >= 35 {
49 return Err(DecodeError("varu32 overflow"));
50 }
51 }
52 Err(DecodeError("unexpected eof (varu32)"))
53}
54
55#[inline]
56pub fn read_varu64(bytes: &[u8], pos: &mut usize) -> Result<u64, DecodeError> {
57 let mut result = 0u64;
58 let mut shift = 0u32;
59 while *pos < bytes.len() {
60 let byte = bytes[*pos];
61 *pos += 1;
62 result |= ((byte & 0x7F) as u64) << shift;
63 if byte & 0x80 == 0 {
64 return Ok(result);
65 }
66 shift += 7;
67 if shift >= 70 {
68 return Err(DecodeError("varu64 overflow"));
69 }
70 }
71 Err(DecodeError("unexpected eof (varu64)"))
72}
73
74#[inline]
75pub fn read_vari32(bytes: &[u8], pos: &mut usize) -> Result<i32, DecodeError> {
76 let raw = read_varu32(bytes, pos)?;
77 Ok(((raw >> 1) as i32) ^ (-((raw & 1) as i32)))
78}
79
80#[inline]
81pub fn read_vari64(bytes: &[u8], pos: &mut usize) -> Result<i64, DecodeError> {
82 let raw = read_varu64(bytes, pos)?;
83 Ok(((raw >> 1) as i64) ^ (-((raw & 1) as i64)))
84}
85
86#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
87pub struct IpKey {
88 pub bytes: [u8; 16],
89 pub len: u8,
90}
91
92impl IpKey {
93 pub fn from(addr: &IpAddr) -> Self {
94 match addr {
95 IpAddr::V4(v4) => {
96 let mut bytes = [0u8; 16];
97 bytes[..4].copy_from_slice(&v4.octets());
98 Self { bytes, len: 4 }
99 }
100 IpAddr::V6(v6) => {
101 let mut bytes = [0u8; 16];
102 bytes.copy_from_slice(&v6.octets());
103 Self { bytes, len: 16 }
104 }
105 }
106 }
107
108 pub fn to_ip(self) -> IpAddr {
109 if self.len == 4 {
110 IpAddr::V4(Ipv4Addr::new(
111 self.bytes[0],
112 self.bytes[1],
113 self.bytes[2],
114 self.bytes[3],
115 ))
116 } else {
117 IpAddr::V6(Ipv6Addr::from(self.bytes))
118 }
119 }
120}
121
122#[inline]
123pub fn write_ip(buf: &mut Vec<u8>, addr: &IpAddr) {
124 match addr {
125 IpAddr::V4(v4) => {
126 buf.push(0);
127 buf.extend_from_slice(&v4.octets());
128 }
129 IpAddr::V6(v6) => {
130 buf.push(1);
131 buf.extend_from_slice(&v6.octets());
132 }
133 }
134}
135
136#[inline]
137pub fn read_ip(bytes: &[u8], pos: &mut usize) -> Result<IpAddr, DecodeError> {
138 if *pos >= bytes.len() {
139 return Err(DecodeError("unexpected eof (ip tag)"));
140 }
141 let tag = bytes[*pos];
142 *pos += 1;
143 match tag {
144 0 => {
145 if *pos + 4 > bytes.len() {
146 return Err(DecodeError("unexpected eof (ipv4)"));
147 }
148 let mut octets = [0u8; 4];
149 octets.copy_from_slice(&bytes[*pos..*pos + 4]);
150 *pos += 4;
151 Ok(IpAddr::V4(Ipv4Addr::from(octets)))
152 }
153 1 => {
154 if *pos + 16 > bytes.len() {
155 return Err(DecodeError("unexpected eof (ipv6)"));
156 }
157 let mut octets = [0u8; 16];
158 octets.copy_from_slice(&bytes[*pos..*pos + 16]);
159 *pos += 16;
160 Ok(IpAddr::V6(Ipv6Addr::from(octets)))
161 }
162 _ => Err(DecodeError("invalid ip tag")),
163 }
164}
165
166#[inline]
167pub fn write_bytes(buf: &mut Vec<u8>, data: &[u8]) {
168 write_varu32(buf, data.len() as u32);
169 buf.extend_from_slice(data);
170}
171
172#[inline]
173pub fn read_bytes<'a>(bytes: &'a [u8], pos: &mut usize) -> Result<&'a [u8], DecodeError> {
174 let len = read_varu32(bytes, pos)? as usize;
175 if *pos + len > bytes.len() {
176 return Err(DecodeError("unexpected eof (bytes)"));
177 }
178 let slice = &bytes[*pos..*pos + len];
179 *pos += len;
180 Ok(slice)
181}
182
183#[inline]
184pub fn write_string(buf: &mut Vec<u8>, value: &str) {
185 write_bytes(buf, value.as_bytes());
186}
187
188#[inline]
189pub fn read_string<'a>(bytes: &'a [u8], pos: &mut usize) -> Result<&'a str, DecodeError> {
190 let data = read_bytes(bytes, pos)?;
191 std::str::from_utf8(data).map_err(|_| DecodeError("invalid utf8"))
192}
193
194#[inline]
196pub fn write_f64(buf: &mut Vec<u8>, value: f64) {
197 buf.extend_from_slice(&value.to_le_bytes());
198}
199
200#[inline]
202pub fn read_f64(bytes: &[u8], pos: &mut usize) -> Result<f64, DecodeError> {
203 if *pos + 8 > bytes.len() {
204 return Err(DecodeError("unexpected eof (f64)"));
205 }
206 let mut arr = [0u8; 8];
207 arr.copy_from_slice(&bytes[*pos..*pos + 8]);
208 *pos += 8;
209 Ok(f64::from_le_bytes(arr))
210}
211
212#[inline]
214pub fn write_f32(buf: &mut Vec<u8>, value: f32) {
215 buf.extend_from_slice(&value.to_le_bytes());
216}
217
218#[inline]
220pub fn read_f32(bytes: &[u8], pos: &mut usize) -> Result<f32, DecodeError> {
221 if *pos + 4 > bytes.len() {
222 return Err(DecodeError("unexpected eof (f32)"));
223 }
224 let mut arr = [0u8; 4];
225 arr.copy_from_slice(&bytes[*pos..*pos + 4]);
226 *pos += 4;
227 Ok(f32::from_le_bytes(arr))
228}
229
230#[cfg(test)]
231mod tests {
232 use super::*;
233
234 #[test]
237 fn test_varu32_single_byte() {
238 let mut buf = Vec::new();
239 write_varu32(&mut buf, 0);
240 assert_eq!(buf, vec![0]);
241
242 buf.clear();
243 write_varu32(&mut buf, 1);
244 assert_eq!(buf, vec![1]);
245
246 buf.clear();
247 write_varu32(&mut buf, 127);
248 assert_eq!(buf, vec![127]);
249 }
250
251 #[test]
252 fn test_varu32_multi_byte() {
253 let mut buf = Vec::new();
254 write_varu32(&mut buf, 128);
255 assert_eq!(buf, vec![0x80, 0x01]);
256
257 buf.clear();
258 write_varu32(&mut buf, 300);
259 let mut pos = 0;
260 assert_eq!(read_varu32(&buf, &mut pos).unwrap(), 300);
261
262 buf.clear();
263 write_varu32(&mut buf, 16384);
264 pos = 0;
265 assert_eq!(read_varu32(&buf, &mut pos).unwrap(), 16384);
266 }
267
268 #[test]
269 fn test_varu32_max() {
270 let mut buf = Vec::new();
271 write_varu32(&mut buf, u32::MAX);
272 let mut pos = 0;
273 assert_eq!(read_varu32(&buf, &mut pos).unwrap(), u32::MAX);
274 }
275
276 #[test]
277 fn test_varu32_roundtrip() {
278 let values = [
279 0,
280 1,
281 127,
282 128,
283 255,
284 256,
285 16383,
286 16384,
287 2097151,
288 2097152,
289 u32::MAX,
290 ];
291 for &val in &values {
292 let mut buf = Vec::new();
293 write_varu32(&mut buf, val);
294 let mut pos = 0;
295 assert_eq!(
296 read_varu32(&buf, &mut pos).unwrap(),
297 val,
298 "Failed for {}",
299 val
300 );
301 }
302 }
303
304 #[test]
305 fn test_varu64_roundtrip() {
306 let values = [0u64, 1, 127, 128, 255, 16384, u32::MAX as u64, u64::MAX];
307 for &val in &values {
308 let mut buf = Vec::new();
309 write_varu64(&mut buf, val);
310 let mut pos = 0;
311 assert_eq!(
312 read_varu64(&buf, &mut pos).unwrap(),
313 val,
314 "Failed for {}",
315 val
316 );
317 }
318 }
319
320 #[test]
321 fn test_vari32_roundtrip() {
322 let values = [0i32, 1, -1, 127, -128, i32::MAX, i32::MIN];
323 for &val in &values {
324 let mut buf = Vec::new();
325 write_vari32(&mut buf, val);
326 let mut pos = 0;
327 assert_eq!(
328 read_vari32(&buf, &mut pos).unwrap(),
329 val,
330 "Failed for {}",
331 val
332 );
333 }
334 }
335
336 #[test]
337 fn test_vari64_roundtrip() {
338 let values = [0i64, 1, -1, 127, -128, i64::MAX, i64::MIN];
339 for &val in &values {
340 let mut buf = Vec::new();
341 write_vari64(&mut buf, val);
342 let mut pos = 0;
343 assert_eq!(
344 read_vari64(&buf, &mut pos).unwrap(),
345 val,
346 "Failed for {}",
347 val
348 );
349 }
350 }
351
352 #[test]
353 fn test_varu32_eof() {
354 let buf = vec![0x80]; let mut pos = 0;
356 assert!(read_varu32(&buf, &mut pos).is_err());
357 }
358
359 #[test]
360 fn test_varu32_overflow() {
361 let buf = vec![0x80, 0x80, 0x80, 0x80, 0x80, 0x01];
363 let mut pos = 0;
364 assert!(read_varu32(&buf, &mut pos).is_err());
365 }
366
367 #[test]
370 fn test_ip_key_ipv4() {
371 let addr = IpAddr::V4(Ipv4Addr::new(192, 168, 1, 1));
372 let key = IpKey::from(&addr);
373 assert_eq!(key.len, 4);
374 assert_eq!(key.bytes[..4], [192, 168, 1, 1]);
375 assert_eq!(key.to_ip(), addr);
376 }
377
378 #[test]
379 fn test_ip_key_ipv6() {
380 let addr = IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1));
381 let key = IpKey::from(&addr);
382 assert_eq!(key.len, 16);
383 assert_eq!(key.to_ip(), addr);
384 }
385
386 #[test]
387 fn test_ip_key_ordering() {
388 let ip1 = IpKey::from(&IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)));
389 let ip2 = IpKey::from(&IpAddr::V4(Ipv4Addr::new(10, 0, 0, 2)));
390 let ip3 = IpKey::from(&IpAddr::V4(Ipv4Addr::new(192, 168, 1, 1)));
391
392 assert!(ip1 < ip2);
393 assert!(ip2 < ip3);
394 }
395
396 #[test]
397 fn test_write_read_ip_v4() {
398 let addr = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
399 let mut buf = Vec::new();
400 write_ip(&mut buf, &addr);
401
402 assert_eq!(buf.len(), 5); assert_eq!(buf[0], 0); let mut pos = 0;
406 let decoded = read_ip(&buf, &mut pos).unwrap();
407 assert_eq!(decoded, addr);
408 }
409
410 #[test]
411 fn test_write_read_ip_v6() {
412 let addr = IpAddr::V6(Ipv6Addr::LOCALHOST);
413 let mut buf = Vec::new();
414 write_ip(&mut buf, &addr);
415
416 assert_eq!(buf.len(), 17); assert_eq!(buf[0], 1); let mut pos = 0;
420 let decoded = read_ip(&buf, &mut pos).unwrap();
421 assert_eq!(decoded, addr);
422 }
423
424 #[test]
425 fn test_read_ip_invalid_tag() {
426 let buf = vec![2, 0, 0, 0, 0]; let mut pos = 0;
428 assert!(read_ip(&buf, &mut pos).is_err());
429 }
430
431 #[test]
432 fn test_read_ip_truncated_v4() {
433 let buf = vec![0, 192, 168]; let mut pos = 0;
435 assert!(read_ip(&buf, &mut pos).is_err());
436 }
437
438 #[test]
439 fn test_read_ip_truncated_v6() {
440 let buf = vec![1, 0, 0, 0, 0, 0, 0, 0, 0]; let mut pos = 0;
442 assert!(read_ip(&buf, &mut pos).is_err());
443 }
444
445 #[test]
448 fn test_write_read_bytes_empty() {
449 let mut buf = Vec::new();
450 write_bytes(&mut buf, &[]);
451
452 let mut pos = 0;
453 let decoded = read_bytes(&buf, &mut pos).unwrap();
454 assert!(decoded.is_empty());
455 }
456
457 #[test]
458 fn test_write_read_bytes_small() {
459 let data = b"hello";
460 let mut buf = Vec::new();
461 write_bytes(&mut buf, data);
462
463 let mut pos = 0;
464 let decoded = read_bytes(&buf, &mut pos).unwrap();
465 assert_eq!(decoded, data);
466 }
467
468 #[test]
469 fn test_write_read_bytes_large() {
470 let data: Vec<u8> = (0..1000).map(|i| (i % 256) as u8).collect();
471 let mut buf = Vec::new();
472 write_bytes(&mut buf, &data);
473
474 let mut pos = 0;
475 let decoded = read_bytes(&buf, &mut pos).unwrap();
476 assert_eq!(decoded, &data[..]);
477 }
478
479 #[test]
480 fn test_write_read_string() {
481 let s = "Hello, World! 🌍";
482 let mut buf = Vec::new();
483 write_string(&mut buf, s);
484
485 let mut pos = 0;
486 let decoded = read_string(&buf, &mut pos).unwrap();
487 assert_eq!(decoded, s);
488 }
489
490 #[test]
491 fn test_read_string_invalid_utf8() {
492 let mut buf = Vec::new();
493 write_varu32(&mut buf, 3);
494 buf.extend_from_slice(&[0xFF, 0xFE, 0xFD]); let mut pos = 0;
497 assert!(read_string(&buf, &mut pos).is_err());
498 }
499
500 #[test]
501 fn test_read_bytes_truncated() {
502 let mut buf = Vec::new();
503 write_varu32(&mut buf, 100); buf.extend_from_slice(&[1, 2, 3]); let mut pos = 0;
507 assert!(read_bytes(&buf, &mut pos).is_err());
508 }
509
510 #[test]
513 fn test_multiple_values_sequential() {
514 let mut buf = Vec::new();
515
516 write_varu32(&mut buf, 42);
518 write_ip(&mut buf, &IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)));
519 write_string(&mut buf, "test");
520 write_vari32(&mut buf, -100);
521
522 let mut pos = 0;
524 assert_eq!(read_varu32(&buf, &mut pos).unwrap(), 42);
525 assert_eq!(
526 read_ip(&buf, &mut pos).unwrap(),
527 IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1))
528 );
529 assert_eq!(read_string(&buf, &mut pos).unwrap(), "test");
530 assert_eq!(read_vari32(&buf, &mut pos).unwrap(), -100);
531 assert_eq!(pos, buf.len()); }
533
534 #[test]
535 fn test_decode_error_display() {
536 let err = DecodeError("test error");
537 assert_eq!(err.0, "test error");
538 }
539}