mod bits;
mod builder;
mod reader;
mod traits;
mod concat;
#[cfg(test)]
mod tests {
use crate::{builder::ByteBuilder, reader::ByteReader, traits::{Builder, Byteable, Reader}};
#[test]
fn test_byte_builder_basic_types() {
let mut builder = ByteBuilder::new();
builder.push_u8(1);
builder.push_u16(2);
builder.push_u32(3);
builder.push_u64(4);
builder.push_u128(5);
builder.push_i8(-1);
builder.push_i16(-2);
builder.push_i32(-3);
builder.push_i64(-4);
builder.push_i128(-5);
builder.push_f32(1.0);
builder.push_f64(2.0);
builder.push_bool(true);
builder.push_bool(false);
let bytes = &builder.bytes;
let mut reader = ByteReader::new(bytes);
assert_eq!(reader.read_u8(), Some(1));
assert_eq!(reader.read_u16(), Some(2));
assert_eq!(reader.read_u32(), Some(3));
assert_eq!(reader.read_u64(), Some(4));
assert_eq!(reader.read_u128(), Some(5));
assert_eq!(reader.read_i8(), Some(-1));
assert_eq!(reader.read_i16(), Some(-2));
assert_eq!(reader.read_i32(), Some(-3));
assert_eq!(reader.read_i64(), Some(-4));
assert_eq!(reader.read_i128(), Some(-5));
assert_eq!(reader.read_f32(), Some(1.0));
assert_eq!(reader.read_f64(), Some(2.0));
assert_eq!(reader.read_bool(), Some(true));
assert_eq!(reader.read_bool(), Some(false));
assert_eq!(reader.remaining(), 0);
}
#[test]
fn test_byte_builder_strings_and_bytes() {
let mut builder = ByteBuilder::new();
builder.push_len_prefixed_str("Hello");
builder.push_len_prefixed_bytes(&[1, 2, 3]);
builder.push_str("World");
builder.push_bytes(&[4, 5, 6]);
let bytes = &builder.bytes;
let mut reader = ByteReader::new(bytes);
assert_eq!(reader.read_len_prefixed_str(), Some("Hello".to_string()));
assert_eq!(reader.read_len_prefixed_bytes(), Some(vec![1, 2, 3]));
assert_eq!(reader.read_str(5), Some("World".to_string()));
assert_eq!(reader.read_bytes(3), Some(vec![4, 5, 6]));
}
#[test]
fn test_byte_builder_edge_cases() {
let mut builder = ByteBuilder::new();
builder.push_len_prefixed_str("");
builder.push_len_prefixed_bytes(&[]);
builder.push_str("");
builder.push_bytes(&[]);
let bytes = &builder.bytes;
let mut reader = ByteReader::new(bytes);
assert_eq!(reader.read_len_prefixed_str(), Some("".to_string()));
assert_eq!(reader.read_len_prefixed_bytes(), Some(vec![]));
assert_eq!(reader.read_bytes(0), Some(vec![]));
assert_eq!(reader.remaining(), 0);
}
#[test]
fn test_byte_builder_chaining() {
let mut builder = ByteBuilder::new();
builder
.with_u8(1)
.with_u16(2)
.with_bool(true)
.with_len_prefixed_str("test")
.with_bytes(&[1, 2, 3]);
let bytes = &builder.bytes;
let mut reader = ByteReader::new(bytes);
assert_eq!(reader.read_u8(), Some(1));
assert_eq!(reader.read_u16(), Some(2));
assert_eq!(reader.read_bool(), Some(true));
assert_eq!(reader.read_len_prefixed_str(), Some("test".to_string()));
assert_eq!(reader.read_bytes(3), Some(vec![1, 2, 3]));
}
#[test]
fn test_byte_reader_edge_cases() {
let bytes = vec![1, 2, 3];
let mut reader = ByteReader::new(&bytes);
assert_eq!(reader.remaining(), 3);
assert_eq!(reader.read_u8(), Some(1));
assert_eq!(reader.remaining(), 2);
assert!(reader.skip(1));
assert_eq!(reader.remaining(), 1);
assert_eq!(reader.read_u8(), Some(3));
assert_eq!(reader.read_u8(), None);
assert_eq!(reader.read_u16(), None);
assert!(!reader.skip(1));
reader.reset();
assert_eq!(reader.remaining(), 3);
assert_eq!(reader.read_u8(), Some(1));
}
#[test]
fn test_bit_builder_basic_operations() {
use crate::bits::builder::BitBuilder;
let mut bit_builder = BitBuilder::new();
assert_eq!(bit_builder.bytes.len(), 0);
assert_eq!(bit_builder.bit_offset, 0);
bit_builder.push_bit(true);
assert_eq!(bit_builder.bytes.len(), 1);
assert_eq!(bit_builder.bit_offset, 1);
assert_eq!(bit_builder.bytes[0], 0b10000000);
bit_builder.push_bit(false);
bit_builder.push_bit(true);
assert_eq!(bit_builder.bit_offset, 3);
assert_eq!(bit_builder.bytes[0], 0b10100000);
for _ in 0..5 {
bit_builder.push_bit(false);
}
assert_eq!(bit_builder.bit_offset, 8);
assert_eq!(bit_builder.bytes[0], 0b10100000);
bit_builder.push_bit(true);
assert_eq!(bit_builder.bytes.len(), 2);
assert_eq!(bit_builder.bit_offset, 1);
assert_eq!(bit_builder.bytes[1], 0b10000000);
}
#[test]
fn test_bit_builder_u8_operations() {
use crate::bits::builder::BitBuilder;
use crate::bits::reader::BitReader;
let mut bit_builder = BitBuilder::new();
bit_builder.push_u8(0b11010010);
assert_eq!(bit_builder.bytes.len(), 1);
assert_eq!(bit_builder.bit_offset, 8);
assert_eq!(bit_builder.bytes[0], 0b11010010);
bit_builder.push_u8(0b10111010);
assert_eq!(bit_builder.bytes.len(), 2);
assert_eq!(bit_builder.bytes[1], 0b10111010);
let bytes = bit_builder.build();
let mut bit_reader = BitReader::new(&bytes);
assert_eq!(bit_reader.read_u8(), Some(0b11010010));
assert_eq!(bit_reader.read_u8(), Some(0b10111010));
assert_eq!(bit_reader.read_u8(), None);
}
#[test]
fn test_bit_builder_mixed_operations() {
use crate::bits::builder::BitBuilder;
use crate::bits::reader::BitReader;
let mut bit_builder = BitBuilder::new();
bit_builder.push_bit(true);
bit_builder.push_bit(false);
bit_builder.push_bit(true);
bit_builder.push_u8(0b11001100);
let bytes = bit_builder.build();
let mut bit_reader = BitReader::new(&bytes);
assert_eq!(bit_reader.read_bit(), Some(true)); assert_eq!(bit_reader.read_bit(), Some(false)); assert_eq!(bit_reader.read_bit(), Some(true));
assert_eq!(bit_reader.read_bit(), Some(true)); assert_eq!(bit_reader.read_bit(), Some(true)); assert_eq!(bit_reader.read_bit(), Some(false)); assert_eq!(bit_reader.read_bit(), Some(false)); assert_eq!(bit_reader.read_bit(), Some(true));
assert_eq!(bit_reader.read_bit(), Some(true)); assert_eq!(bit_reader.read_bit(), Some(false)); assert_eq!(bit_reader.read_bit(), Some(false));
assert_eq!(bit_reader.read_bit(), Some(false)); assert_eq!(bit_reader.read_bit(), Some(false)); assert_eq!(bit_reader.read_bit(), Some(false)); assert_eq!(bit_reader.read_bit(), Some(false)); assert_eq!(bit_reader.read_bit(), Some(false));
assert_eq!(bit_reader.read_bit(), None);
}
#[test]
fn test_bit_builder_edge_cases() {
use crate::bits::builder::BitBuilder;
use crate::bits::reader::BitReader;
let bit_builder = BitBuilder::with_capacity(10);
assert_eq!(bit_builder.bytes.capacity(), 10);
let initial_bytes = vec![0xFF, 0x00];
let mut bit_builder = BitBuilder::from_bytes(initial_bytes.clone());
assert_eq!(bit_builder.bytes, initial_bytes);
assert_eq!(bit_builder.bit_offset, 0);
bit_builder.push_bit(true);
assert_eq!(bit_builder.bytes.len(), 2);
assert_eq!(bit_builder.bytes[0], 0xFF); assert_eq!(bit_builder.bytes[1], 0b10000000);
let empty_builder = BitBuilder::new();
let bytes = empty_builder.build();
assert_eq!(bytes.len(), 0);
let mut reader = BitReader::new(&bytes);
assert_eq!(reader.read_bit(), None);
assert_eq!(reader.remaining(), 0);
}
#[test]
fn test_bit_reader_comprehensive() {
use crate::bits::builder::BitBuilder;
use crate::bits::reader::BitReader;
let mut bit_builder = BitBuilder::new();
bit_builder.push_u8(0b11010010);
bit_builder.push_u8(0b10111010);
let bytes = bit_builder.build();
let mut bit_reader = BitReader::new(&bytes);
assert_eq!(bit_reader.remaining(), 16);
assert_eq!(bit_reader.read_bit(), Some(true)); assert_eq!(bit_reader.remaining(), 15);
assert_eq!(bit_reader.read_bit(), Some(true)); assert_eq!(bit_reader.read_bit(), Some(false)); assert_eq!(bit_reader.read_bit(), Some(true)); assert_eq!(bit_reader.read_bit(), Some(false)); assert_eq!(bit_reader.read_bit(), Some(false)); assert_eq!(bit_reader.read_bit(), Some(true)); assert_eq!(bit_reader.read_bit(), Some(false)); assert_eq!(bit_reader.remaining(), 8);
assert_eq!(bit_reader.read_bit(), Some(true)); assert_eq!(bit_reader.read_bit(), Some(false)); assert_eq!(bit_reader.read_bit(), Some(true)); assert_eq!(bit_reader.read_bit(), Some(true)); assert_eq!(bit_reader.read_bit(), Some(true)); assert_eq!(bit_reader.read_bit(), Some(false)); assert_eq!(bit_reader.read_bit(), Some(true)); assert_eq!(bit_reader.read_bit(), Some(false)); assert_eq!(bit_reader.remaining(), 0);
assert_eq!(bit_reader.read_bit(), None);
let mut bit_reader2 = BitReader::new(&bytes);
assert_eq!(bit_reader2.read_u8(), Some(0b11010010));
assert_eq!(bit_reader2.read_u8(), Some(0b10111010));
assert_eq!(bit_reader2.read_u8(), None);
let mut bit_reader3 = BitReader::new(&bytes);
assert_eq!(bit_reader3.remaining(), 16);
bit_reader3.read_bit();
assert_eq!(bit_reader3.remaining(), 15);
bit_reader3.read_u8(); assert_eq!(bit_reader3.remaining(), 7);
bit_reader3.reset();
assert_eq!(bit_reader3.remaining(), 16);
assert_eq!(bit_reader3.read_bit(), Some(true));
bit_reader3.reset();
assert!(bit_reader3.skip(1)); assert_eq!(bit_reader3.remaining(), 8);
assert_eq!(bit_reader3.read_u8(), Some(0b10111010));
assert!(!bit_reader3.skip(1)); }
#[test]
fn test_bit_operations_stress() {
use crate::bits::builder::BitBuilder;
use crate::bits::reader::BitReader;
let mut bit_builder = BitBuilder::new();
for i in 0..96 { bit_builder.push_bit(i % 2 == 0);
}
let bytes = bit_builder.build();
let mut bit_reader = BitReader::new(&bytes);
for i in 0..96 {
assert_eq!(bit_reader.read_bit(), Some(i % 2 == 0));
}
assert_eq!(bit_reader.read_bit(), None);
}
#[test]
fn test_byteable_trait() {
let s = S {
str: "Hello World!".to_string(),
val: 42,
};
let mut builder = ByteBuilder::new();
builder.push(s.clone());
let bytes = &builder.bytes;
let mut reader = ByteReader::new(bytes);
assert_eq!(reader.read::<S>(), Some(s));
assert_eq!(reader.remaining(), 0);
}
#[test]
fn test_builder_conversions() {
let slice = [1u8, 2, 3];
let builder = ByteBuilder::from(slice.as_slice());
assert_eq!(builder.bytes, vec![1, 2, 3]);
let vec = vec![4u8, 5, 6];
let builder = ByteBuilder::from(vec);
assert_eq!(builder.bytes, vec![4, 5, 6]);
let mut builder = ByteBuilder::new();
builder.push_u8(7);
let vec: Vec<u8> = builder.into();
assert_eq!(vec, vec![7]);
}
#[derive(Debug, PartialEq, Clone)]
struct S {
pub str: String,
pub val: i32,
}
impl Byteable for S {
fn to_bytes(&self) -> Vec<u8> {
let mut b = ByteBuilder::new();
b.push_len_prefixed_str(&self.str);
b.push_i32(self.val);
b.bytes
}
fn from_bytes<R: Reader>(reader: &mut R) -> Option<Self> {
Some(Self {
str: reader.read_len_prefixed_str()?,
val: reader.read_i32()?,
})
}
}
}