mod error;
mod read_write;
mod serialize;
mod serialize_num;
mod serialize_tuple;
mod sized_vec;
pub type StringSize = u32;
pub use taped::*;
pub use self::{error::*, read_write::*, serialize::*, sized_vec::*};
#[cfg(test)]
mod tests {
use taped::ToTape;
use crate::{
error::{DecodeError, EncodeError},
read_write::{Read, Write},
serialize::Serialize,
sized_vec::{Vec8, Vec16, Vec32},
vec8, vec16, vec32, write_all,
};
fn round_trip<T: Serialize + PartialEq + std::fmt::Debug>(value: T) {
let mut buffer = vec![];
buffer.write(&value).expect("Failed to write");
let mut src = buffer.to_tape();
let decoded = src.read::<T>().expect("Failed to read");
dbg!(&src);
assert_eq!(value, decoded, "Round-trip failed");
assert_eq!(src.rest().len(), 0, "Not all bytes consumed");
}
#[test]
fn test_bool_serialization() {
round_trip(true);
round_trip(false);
}
#[test]
fn test_u8_serialization() {
round_trip(0u8);
round_trip(127u8);
round_trip(255u8);
}
#[test]
fn test_u16_serialization() {
round_trip(0u16);
round_trip(256u16);
round_trip(u16::MAX);
}
#[test]
fn test_u32_serialization() {
round_trip(0u32);
round_trip(65536u32);
round_trip(u32::MAX);
}
#[test]
fn test_signed_integers() {
round_trip(-128i8);
round_trip(127i8);
round_trip(-32768i16);
round_trip(32767i16);
round_trip(i32::MIN);
round_trip(i32::MAX);
round_trip(i64::MIN);
round_trip(i64::MAX);
round_trip(i128::MIN);
round_trip(i128::MAX);
}
#[test]
fn test_floats() {
round_trip(0.0f32);
round_trip(-0.0f32);
round_trip(std::f32::consts::PI);
round_trip(f32::INFINITY);
round_trip(f32::NEG_INFINITY);
round_trip(0.0f64);
round_trip(std::f64::consts::E);
round_trip(f64::INFINITY);
round_trip(f64::NEG_INFINITY);
}
#[test]
fn test_float_nan() {
let mut buffer = vec![];
buffer.write(&f32::NAN).unwrap();
let mut src = buffer.to_tape();
let decoded = src.read::<f32>().unwrap();
assert!(decoded.is_nan(), "NaN not preserved");
}
#[test]
fn test_string_serialization() {
round_trip(String::new());
round_trip("hello".to_string());
round_trip("Hello, World! 🦀".to_string());
round_trip("Multi\nLine\nString".to_string());
let long = "a".repeat(1000);
round_trip(long);
}
#[test]
fn test_string_utf8() {
round_trip("日本語".to_string());
round_trip("Ñoño español".to_string());
round_trip("🎉🎊✨".to_string());
}
#[test]
fn test_tuples() {
round_trip((42u32, true));
round_trip((1u8, 2u16, 3u32));
round_trip(("hello".to_string(), 123i32));
}
#[test]
fn test_nested_tuples() {
round_trip(((1u8, 2u8), (3u8, 4u8)));
}
#[test]
fn test_vec8() {
let empty: Vec8<u32> = vec8![];
round_trip(empty);
let small = vec8![1u32, 2, 3, 4, 5];
round_trip(small);
let max_vec8 = vec8![0u8; 255];
round_trip(max_vec8);
}
#[test]
fn test_vec16() {
let empty: Vec16<u32> = vec16![];
round_trip(empty);
let medium = vec16![100u32; 300];
round_trip(medium);
}
#[test]
fn test_vec32() {
let empty: Vec32<u32> = vec32![];
round_trip(empty);
let large = vec32![42u32; 10000];
round_trip(large);
}
#[test]
fn test_vec_of_strings() {
let strings = vec32!["hello".to_string(), "world".to_string(), "🦀".to_string(),];
round_trip(strings);
}
#[test]
fn test_nested_vecs() {
let nested = vec32![vec8![1u8, 2, 3], vec8![4, 5], vec8![]];
round_trip(nested);
}
#[test]
fn test_little_endian_encoding() {
let mut buffer = vec![];
buffer.write(&0x12345678u32).unwrap();
assert_eq!(buffer, vec![0x78, 0x56, 0x34, 0x12]);
}
#[test]
fn test_string_length_prefix() {
let mut buffer = vec![];
buffer.write(&"abc".to_string()).unwrap();
assert_eq!(buffer[0..4], [3, 0, 0, 0]);
assert_eq!(buffer[4..7], [b'a', b'b', b'c']);
}
#[test]
fn test_vec_length_prefix() {
let mut buffer = vec![];
buffer.write(&vec32![1u8, 2, 3]).unwrap();
assert_eq!(buffer[0..4], [3, 0, 0, 0]);
assert_eq!(buffer[4..7], [1, 2, 3]);
}
#[test]
fn test_empty_buffer_error() {
let buffer = [];
let mut src = buffer.to_tape();
let result = src.read::<u32>();
assert!(matches!(result, Err(DecodeError::Exhausted { .. })));
}
#[test]
fn test_truncated_data() {
let mut buffer = vec![];
buffer.write(&42u32).unwrap();
let truncated = &buffer[0..2];
let mut src = truncated.to_tape();
let result = src.read::<u32>();
assert!(matches!(result, Err(DecodeError::Exhausted { .. })));
}
#[test]
fn test_truncated_string() {
let mut buffer = vec![];
buffer.write(&"hello".to_string()).unwrap();
let truncated = &buffer[0..6]; let mut src = truncated.to_tape();
let result = src.read::<String>();
assert!(matches!(result, Err(DecodeError::Exhausted { .. })));
}
#[test]
fn test_invalid_utf8() {
let mut buffer = vec![];
buffer.extend_from_slice(&[2, 0, 0, 0]);
buffer.extend_from_slice(&[0xFF, 0xFE]);
let mut src = buffer.to_tape();
let result = src.read::<String>();
assert!(matches!(result, Err(DecodeError::Other { .. })));
}
#[test]
fn test_truncated_vec() {
let mut buffer = vec![];
buffer.write(&vec32![1u32, 2, 3]).unwrap();
let truncated = &buffer[0..8]; let mut src = truncated.to_tape();
let result = src.read::<Vec32<u32>>();
assert!(matches!(result, Err(DecodeError::Exhausted { .. })));
}
#[test]
#[cfg(target_pointer_width = "64")]
fn test_array_size_overflow() {
let huge_string = "a".repeat(u32::MAX as usize + 1);
let mut buffer = vec![];
let result = buffer.write(&huge_string);
assert!(matches!(
result,
Err(EncodeError::LengthExceedsPrefix { .. })
));
}
#[test]
fn test_byte_stream_operations() {
let data = [1, 2, 3, 4, 5];
let mut src = data.to_tape();
assert_eq!(src.pos, 0);
assert_eq!(src.rest().len(), 5);
assert_eq!(src.next(), Some(1));
assert_eq!(src.pos, 1);
assert_eq!(src.rest().len(), 4);
src.pos += 2;
assert_eq!(src.pos, 3);
assert_eq!(src.rest().len(), 2);
assert_eq!(src.next(), Some(4));
assert_eq!(src.next(), Some(5));
assert_eq!(src.next(), None);
assert_eq!(src.rest().len(), 0);
}
#[test]
fn test_multiple_values_in_sequence() {
let mut buffer = vec![];
write_all!(buffer;
&42u32,
&"hello".to_string(),
&true,
&vec8![1u8, 2, 3],
)
.unwrap();
let mut src = buffer.to_tape();
let num = src.read::<u32>().unwrap();
assert_eq!(num, 42);
let string = src.read::<String>().unwrap();
assert_eq!(string, "hello");
let boolean = src.read::<bool>().unwrap();
assert!(boolean);
let vec = src.read::<Vec8<u8>>().unwrap();
assert_eq!(vec.into_inner(), vec![1, 2, 3]);
assert_eq!(src.rest().len(), 0);
}
#[test]
fn test_complex_structure() {
let mut buffer = vec![];
buffer.write(&0xCAFEBABEu32).unwrap();
buffer.write(&(1u16, 0u16)).unwrap();
let functions = vec32![("main".to_string(), 0u32), ("helper".to_string(), 100u32),];
buffer.write(&functions).unwrap();
let constants = vec16!["Hello".to_string(), "World".to_string()];
buffer.write(&constants).unwrap();
let mut src = buffer.to_tape();
let magic = src.read::<u32>().unwrap();
assert_eq!(magic, 0xCAFEBABE);
let version = src.read::<(u16, u16)>().unwrap();
assert_eq!(version, (1, 0));
let funcs = src.read::<Vec32<(String, u32)>>().unwrap();
assert_eq!(funcs.len(), 2);
assert_eq!(funcs[0].0, "main");
assert_eq!(funcs[1].1, 100);
let consts = src.read::<Vec16<String>>().unwrap();
assert_eq!(consts.len(), 2);
assert_eq!(consts[0], "Hello");
assert_eq!(src.rest().len(), 0);
}
#[test]
fn test_zero_values() {
round_trip(0u8);
round_trip(0u16);
round_trip(0u32);
round_trip(0i8);
round_trip(0i16);
round_trip(0i32);
round_trip(0i64);
round_trip(0i128);
round_trip(0.0f32);
round_trip(0.0f64);
}
#[test]
fn test_max_values() {
round_trip(u8::MAX);
round_trip(u16::MAX);
round_trip(u32::MAX);
round_trip(i8::MAX);
round_trip(i16::MAX);
round_trip(i32::MAX);
round_trip(i64::MAX);
round_trip(i128::MAX);
}
#[test]
fn test_min_values() {
round_trip(i8::MIN);
round_trip(i16::MIN);
round_trip(i32::MIN);
round_trip(i64::MIN);
round_trip(i128::MIN);
}
}