mod codecs;
mod varint;
mod wire;
pub use codecs::*;
pub use varint::*;
pub use wire::*;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn varint_zero() {
let buf = [0x00u8];
let r = parse_varint(&buf, 0);
assert_eq!(r.varint, Some(0));
assert_eq!(r.varint_ohb, None);
assert_eq!(r.next_pos, 1);
}
#[test]
fn varint_one_byte() {
let buf = [0x01u8];
let r = parse_varint(&buf, 0);
assert_eq!(r.varint, Some(1));
assert_eq!(r.next_pos, 1);
}
#[test]
fn varint_150() {
let buf = [0x96u8, 0x01];
let r = parse_varint(&buf, 0);
assert_eq!(r.varint, Some(150));
assert_eq!(r.next_pos, 2);
assert_eq!(r.varint_ohb, None);
}
#[test]
fn varint_max_u64() {
let buf = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01];
let r = parse_varint(&buf, 0);
assert_eq!(r.varint, Some(u64::MAX));
assert_eq!(r.next_pos, 10);
}
#[test]
fn varint_truncated() {
let buf = [0x80u8, 0x80];
let r = parse_varint(&buf, 0);
assert!(r.varint_gar.is_some());
assert!(r.varint.is_none());
}
#[test]
fn varint_empty_at_end() {
let buf = [0x01u8];
let r = parse_varint(&buf, 1); assert!(r.varint_gar.is_some());
assert_eq!(r.varint_gar.unwrap(), Vec::<u8>::new());
}
#[test]
fn varint_overhang_one() {
let buf = [0x80u8, 0x00];
let r = parse_varint(&buf, 0);
assert_eq!(r.varint, Some(0));
assert_eq!(r.varint_ohb, Some(1));
}
#[test]
fn varint_overhang_two() {
let buf = [0x80u8, 0x80, 0x00];
let r = parse_varint(&buf, 0);
assert_eq!(r.varint, Some(0));
assert_eq!(r.varint_ohb, Some(2));
}
#[test]
fn varint_encode_with_overhang() {
let bytes = encode_varint_bytes(0, Some(1));
assert_eq!(bytes, vec![0x80, 0x00]);
let bytes2 = encode_varint_bytes(0, Some(2));
assert_eq!(bytes2, vec![0x80, 0x80, 0x00]);
let bytes3 = encode_varint_bytes(150, None);
assert_eq!(bytes3, vec![0x96, 0x01]);
}
#[test]
fn varint_encode_roundtrip() {
for val in [0u64, 1, 127, 128, 300, 16383, 16384, u64::MAX] {
let encoded = encode_varint_bytes(val, None);
let r = parse_varint(&encoded, 0);
assert_eq!(r.varint, Some(val), "roundtrip failed for {val}");
assert_eq!(r.next_pos, encoded.len());
}
}
#[test]
fn wiretag_field1_varint() {
let buf = [0x08u8];
let r = parse_wiretag(&buf, 0);
assert_eq!(r.wtype, Some(0));
assert_eq!(r.wfield, Some(1));
assert_eq!(r.wfield_ohb, None);
assert_eq!(r.wfield_oor, None);
}
#[test]
fn wiretag_invalid_wire_type() {
let buf = [0x06u8, 0x00, 0x01];
let r = parse_wiretag(&buf, 0);
assert!(r.wtag_gar.is_some());
assert!(r.wtype.is_none());
}
#[test]
fn wiretag_field_number_zero_is_oor() {
let buf = [0x00u8]; let r = parse_wiretag(&buf, 0);
assert_eq!(r.wfield, Some(0));
assert_eq!(r.wfield_oor, Some(true));
}
#[test]
fn wiretag_overhung() {
let buf = [0x88u8, 0x00];
let r = parse_wiretag(&buf, 0);
assert_eq!(r.wtype, Some(0));
assert_eq!(r.wfield, Some(1));
assert_eq!(r.wfield_ohb, Some(1));
}
#[test]
fn int32_negative() {
assert_eq!(decode_int32(0xFFFFFFFF), -1i32);
}
#[test]
fn int64_negative() {
assert_eq!(decode_int64(u64::MAX), -1i64);
}
#[test]
fn sint32_roundtrip() {
for v in [-1i32, 0, 1, -2, 2, i32::MIN, i32::MAX] {
let encoded = if v >= 0 {
((v as u32) << 1) as u64
} else {
((!v as u32) * 2 + 1) as u64
};
assert_eq!(decode_sint32(encoded), v, "sint32 roundtrip for {v}");
}
}
#[test]
fn sint64_roundtrip() {
for v in [-1i64, 0, 1, -2, 2, i64::MIN, i64::MAX] {
let encoded = if v >= 0 {
(v as u64) << 1
} else {
((!v as u64) << 1) | 1
};
assert_eq!(decode_sint64(encoded), v, "sint64 roundtrip for {v}");
}
}
#[test]
fn fixed32_little_endian() {
let data = [0x01u8, 0x00, 0x00, 0x00];
assert_eq!(decode_fixed32(&data), 1u32);
let data2 = [0xFFu8, 0xFF, 0xFF, 0xFF];
assert_eq!(decode_fixed32(&data2), u32::MAX);
}
#[test]
fn fixed64_little_endian() {
let data = [0x01u8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
assert_eq!(decode_fixed64(&data), 1u64);
}
#[test]
fn double_roundtrip() {
let val = std::f64::consts::PI;
let data = val.to_le_bytes();
assert_eq!(decode_double(&data), val);
}
#[test]
fn float_roundtrip() {
let val = 1.5f32;
let data = val.to_le_bytes();
assert_eq!(decode_float(&data), val);
}
#[test]
fn write_varint_field_roundtrip() {
let mut buf = Vec::new();
write_varint_field(1, 300, &mut buf);
assert_eq!(buf, vec![0x08, 0xAC, 0x02]);
}
#[test]
fn write_len_field_roundtrip() {
let mut buf = Vec::new();
write_len_field(2, b"hi", &mut buf);
assert_eq!(buf, vec![0x12, 0x02, 0x68, 0x69]);
}
}