use bebytes::BeBytes;
#[test]
fn test_insufficient_data_errors() {
#[derive(BeBytes, Debug, PartialEq)]
struct TestStruct {
a: u32,
b: u16,
c: u8,
}
assert_eq!(TestStruct::field_size(), 7);
for i in 0..7 {
let bytes = vec![0xFF; i];
let result = TestStruct::try_from_be_bytes(&bytes);
assert!(
result.is_err(),
"Should fail with {} bytes, but succeeded",
i
);
let result = TestStruct::try_from_le_bytes(&bytes);
assert!(
result.is_err(),
"Should fail with {} bytes, but succeeded",
i
);
}
let bytes = vec![0xFF; 7];
assert!(TestStruct::try_from_be_bytes(&bytes).is_ok());
assert!(TestStruct::try_from_le_bytes(&bytes).is_ok());
}
#[test]
fn test_bit_field_overflow_protection() {
#[derive(BeBytes, Debug, PartialEq)]
struct BitFieldTest {
#[bits(3)]
three_bits: u8, #[bits(5)]
five_bits: u8, }
let test = BitFieldTest {
three_bits: 255, five_bits: 255, };
let bytes = test.to_be_bytes();
let (parsed, _) = BitFieldTest::try_from_be_bytes(&bytes).unwrap();
assert_eq!(parsed.three_bits, 7); assert_eq!(parsed.five_bits, 31); }
#[test]
fn test_zero_sized_arrays() {
#[derive(BeBytes, Debug, PartialEq)]
struct ZeroArrayStruct {
header: u16,
empty: [u8; 0],
footer: u32,
}
let test = ZeroArrayStruct {
header: 0x1234,
empty: [],
footer: 0xABCDEF00,
};
assert_eq!(ZeroArrayStruct::field_size(), 6);
let be_bytes = test.to_be_bytes();
let le_bytes = test.to_le_bytes();
assert_eq!(be_bytes.len(), 6);
assert_eq!(le_bytes.len(), 6);
let (be_parsed, _) = ZeroArrayStruct::try_from_be_bytes(&be_bytes).unwrap();
let (le_parsed, _) = ZeroArrayStruct::try_from_le_bytes(&le_bytes).unwrap();
assert_eq!(be_parsed, test);
assert_eq!(le_parsed, test);
}
#[test]
fn test_alternating_bit_patterns() {
#[derive(BeBytes, Debug, PartialEq)]
struct AlternatingBits {
#[bits(1)]
b0: u8,
#[bits(1)]
b1: u8,
#[bits(1)]
b2: u8,
#[bits(1)]
b3: u8,
#[bits(1)]
b4: u8,
#[bits(1)]
b5: u8,
#[bits(1)]
b6: u8,
#[bits(1)]
b7: u8,
}
let test = AlternatingBits {
b0: 1,
b1: 0,
b2: 1,
b3: 0,
b4: 1,
b5: 0,
b6: 1,
b7: 0,
};
let bytes = test.to_be_bytes();
assert_eq!(bytes[0], 0b10101010);
let (parsed, _) = AlternatingBits::try_from_be_bytes(&bytes).unwrap();
assert_eq!(parsed, test);
let test2 = AlternatingBits {
b0: 0,
b1: 1,
b2: 0,
b3: 1,
b4: 0,
b5: 1,
b6: 0,
b7: 1,
};
let bytes2 = test2.to_be_bytes();
assert_eq!(bytes2[0], 0b01010101);
}
#[test]
fn test_endianness_differences() {
#[derive(BeBytes, Debug, PartialEq)]
struct EndianTest {
value: u32,
}
let test = EndianTest { value: 0x12345678 };
let be_bytes = test.to_be_bytes();
let le_bytes = test.to_le_bytes();
assert_eq!(be_bytes, vec![0x12, 0x34, 0x56, 0x78]);
assert_eq!(le_bytes, vec![0x78, 0x56, 0x34, 0x12]);
let (wrong, _) = EndianTest::try_from_le_bytes(&be_bytes).unwrap();
assert_eq!(wrong.value, 0x78563412);
let (wrong, _) = EndianTest::try_from_be_bytes(&le_bytes).unwrap();
assert_eq!(wrong.value, 0x78563412);
}
#[test]
fn test_signed_negative_values() {
#[derive(BeBytes, Debug, PartialEq)]
struct SignedTest {
i8_val: i8,
i16_val: i16,
i32_val: i32,
i64_val: i64,
i128_val: i128,
}
let test = SignedTest {
i8_val: -1,
i16_val: -1,
i32_val: -1,
i64_val: -1,
i128_val: -1,
};
let be_bytes = test.to_be_bytes();
let le_bytes = test.to_le_bytes();
assert!(be_bytes.iter().all(|&b| b == 0xFF));
assert!(le_bytes.iter().all(|&b| b == 0xFF));
let (be_parsed, _) = SignedTest::try_from_be_bytes(&be_bytes).unwrap();
let (le_parsed, _) = SignedTest::try_from_le_bytes(&le_bytes).unwrap();
assert_eq!(be_parsed, test);
assert_eq!(le_parsed, test);
}
#[test]
fn test_max_bit_field_values() {
#[derive(BeBytes, Debug, PartialEq)]
struct MaxBitFields {
#[bits(1)]
one_bit: u8, #[bits(2)]
two_bits: u8, #[bits(3)]
three_bits: u8, #[bits(4)]
four_bits: u8, #[bits(5)]
five_bits: u8, #[bits(6)]
six_bits: u8, #[bits(7)]
seven_bits: u8, #[bits(4)]
padding: u8, }
let test = MaxBitFields {
one_bit: 1,
two_bits: 3,
three_bits: 7,
four_bits: 15,
five_bits: 31,
six_bits: 63,
seven_bits: 127,
padding: 0,
};
let bytes = test.to_be_bytes();
let (parsed, _) = MaxBitFields::try_from_be_bytes(&bytes).unwrap();
assert_eq!(parsed, test);
let overflow_test = MaxBitFields {
one_bit: 3, two_bits: 7, three_bits: 15, four_bits: 31, five_bits: 63, six_bits: 127, seven_bits: 255, padding: 255, };
let overflow_bytes = overflow_test.to_be_bytes();
let (overflow_parsed, _) = MaxBitFields::try_from_be_bytes(&overflow_bytes).unwrap();
assert_eq!(overflow_parsed.one_bit, 1);
assert_eq!(overflow_parsed.two_bits, 3);
assert_eq!(overflow_parsed.three_bits, 7);
assert_eq!(overflow_parsed.four_bits, 15);
assert_eq!(overflow_parsed.five_bits, 31);
assert_eq!(overflow_parsed.six_bits, 63);
assert_eq!(overflow_parsed.seven_bits, 127);
assert_eq!(overflow_parsed.padding, 15);
}
#[test]
fn test_bit_position_arithmetic() {
#[derive(BeBytes, Debug, PartialEq)]
struct LargeBitStruct {
#[bits(32)]
field1: u32,
#[bits(32)]
field2: u32,
#[bits(32)]
field3: u32,
#[bits(32)]
field4: u32,
}
let test = LargeBitStruct {
field1: 0x12345678,
field2: 0x9ABCDEF0,
field3: 0x13579BDF,
field4: 0x2468ACE0,
};
assert_eq!(LargeBitStruct::field_size(), 16);
let bytes = test.to_be_bytes();
assert_eq!(bytes.len(), 16);
let (parsed, consumed) = LargeBitStruct::try_from_be_bytes(&bytes).unwrap();
assert_eq!(consumed, 16);
assert_eq!(parsed, test);
}
#[test]
fn test_single_byte_crossing() {
#[derive(BeBytes, Debug, PartialEq)]
struct ByteCrossing {
#[bits(7)]
seven: u8,
#[bits(2)]
two: u8,
#[bits(7)]
seven2: u8,
}
let test = ByteCrossing {
seven: 0x7F, two: 0x3, seven2: 0x7F, };
let bytes = test.to_be_bytes();
assert_eq!(bytes.len(), 2);
assert_eq!(bytes[0], 0xFF);
assert_eq!(bytes[1], 0xFF);
let (parsed, _) = ByteCrossing::try_from_be_bytes(&bytes).unwrap();
assert_eq!(parsed.seven, 0x7F);
assert_eq!(parsed.two, 0x3);
assert_eq!(parsed.seven2, 0x7F);
assert_eq!(parsed, test);
}
#[test]
fn test_empty_struct() {
#[derive(BeBytes, Debug, PartialEq)]
struct EmptyStruct {}
let test = EmptyStruct {};
assert_eq!(EmptyStruct::field_size(), 0);
let bytes = test.to_be_bytes();
assert_eq!(bytes.len(), 0);
let result = EmptyStruct::try_from_be_bytes(&[]);
assert!(result.is_err());
let (parsed2, consumed2) = EmptyStruct::try_from_be_bytes(&[1, 2, 3]).unwrap();
assert_eq!(consumed2, 0);
assert_eq!(parsed2, test);
}
#[test]
fn test_consecutive_parses() {
#[derive(BeBytes, Debug, PartialEq)]
struct Small {
value: u16,
}
let s1 = Small { value: 0x1234 };
let s2 = Small { value: 0x5678 };
let s3 = Small { value: 0x9ABC };
let mut buffer = Vec::new();
buffer.extend_from_slice(&s1.to_be_bytes());
buffer.extend_from_slice(&s2.to_be_bytes());
buffer.extend_from_slice(&s3.to_be_bytes());
let (p1, consumed1) = Small::try_from_be_bytes(&buffer).unwrap();
assert_eq!(p1, s1);
assert_eq!(consumed1, 2);
let (p2, consumed2) = Small::try_from_be_bytes(&buffer[consumed1..]).unwrap();
assert_eq!(p2, s2);
assert_eq!(consumed2, 2);
let (p3, consumed3) = Small::try_from_be_bytes(&buffer[consumed1 + consumed2..]).unwrap();
assert_eq!(p3, s3);
assert_eq!(consumed3, 2);
}