use bebytes::BeBytes;
#[test]
fn test_bit_to_byte_conversion() {
#[derive(BeBytes, Debug, PartialEq)]
struct BitToByteTest {
#[bits(8)]
one_byte: u8,
#[bits(16)]
two_bytes: u16,
#[bits(32)]
four_bytes: u32,
}
let test = BitToByteTest {
one_byte: 0xFF,
two_bytes: 0xFFFF,
four_bytes: 0xFFFFFFFF,
};
assert_eq!(BitToByteTest::field_size(), 7);
let bytes = test.to_be_bytes();
assert_eq!(bytes.len(), 7);
assert_eq!(bytes[0], 0xFF); assert_eq!(bytes[1], 0xFF); assert_eq!(bytes[2], 0xFF); assert_eq!(bytes[3], 0xFF); assert_eq!(bytes[4], 0xFF); assert_eq!(bytes[5], 0xFF); assert_eq!(bytes[6], 0xFF); }
#[test]
fn test_unaligned_bit_fields() {
#[derive(BeBytes, Debug, PartialEq)]
struct UnalignedBits {
#[bits(3)]
three_bits: u8,
#[bits(5)]
five_bits: u8,
#[bits(7)]
seven_bits: u8,
#[bits(9)]
nine_bits: u16,
}
let test = UnalignedBits {
three_bits: 0b111,
five_bits: 0b11111,
seven_bits: 0b1111111,
nine_bits: 0b111111111,
};
assert_eq!(UnalignedBits::field_size(), 3);
let bytes = test.to_be_bytes();
assert_eq!(bytes.len(), 3);
let (parsed, consumed) = UnalignedBits::try_from_be_bytes(&bytes).unwrap();
assert_eq!(parsed, test);
assert_eq!(consumed, 3);
}
#[test]
fn test_byte_alignment_padding() {
#[derive(BeBytes, Debug, PartialEq)]
struct PaddingTest {
#[bits(4)]
nibble: u8,
#[bits(4)]
another_nibble: u8,
#[bits(3)]
three_bits: u8,
#[bits(5)]
five_bits: u8,
}
let test = PaddingTest {
nibble: 0xF,
another_nibble: 0xF,
three_bits: 0b111,
five_bits: 0b11111,
};
assert_eq!(PaddingTest::field_size(), 2);
let bytes = test.to_be_bytes();
assert_eq!(bytes.len(), 2);
assert_eq!(bytes[0], 0xFF);
assert_eq!(bytes[1], 0xFF);
}
#[test]
fn test_large_bit_fields() {
#[derive(BeBytes, Debug, PartialEq)]
struct LargeBitFields {
large_field: u64, very_large_field: u128, }
let test = LargeBitFields {
large_field: 0xFFFFFFFFFFFFFFFF,
very_large_field: 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF,
};
assert_eq!(LargeBitFields::field_size(), 24);
let bytes = test.to_be_bytes();
assert_eq!(bytes.len(), 24);
assert!(bytes.iter().all(|&b| b == 0xFF));
}
#[test]
fn test_div_ceil_behavior() {
#[derive(BeBytes, Debug, PartialEq)]
struct OneByteStruct {
#[bits(1)]
one_bit: u8,
#[bits(7)]
seven_bits: u8,
}
assert_eq!(OneByteStruct::field_size(), 1);
#[derive(BeBytes, Debug, PartialEq)]
struct TwoByteStruct {
#[bits(9)]
nine_bits: u16,
#[bits(7)]
seven_bits: u8,
}
assert_eq!(TwoByteStruct::field_size(), 2);
#[derive(BeBytes, Debug, PartialEq)]
struct ThreeByteStruct {
#[bits(17)]
seventeen_bits: u32,
#[bits(7)]
seven_bits: u8,
}
assert_eq!(ThreeByteStruct::field_size(), 3);
let test = ThreeByteStruct {
seventeen_bits: 0x1FFFF, seven_bits: 0x7F, };
let bytes = test.to_be_bytes();
assert_eq!(bytes.len(), 3);
assert_eq!(bytes[0], 0xFF); assert_eq!(bytes[1], 0xFF); assert_eq!(bytes[2], 0xFF);
let mut parse_bytes = vec![0u8; 10];
parse_bytes[..3].copy_from_slice(&bytes);
let (parsed, consumed) = ThreeByteStruct::try_from_be_bytes(&parse_bytes).unwrap();
assert_eq!(consumed, 3);
assert_eq!(parsed.seventeen_bits, 0x1FFFF);
assert_eq!(parsed.seven_bits, 0x7F);
}
#[test]
fn test_mixed_aligned_unaligned() {
#[derive(BeBytes, Debug, PartialEq)]
struct MixedAlignment {
regular_u8: u8, #[bits(3)]
three_bits: u8, #[bits(5)]
five_bits: u8, regular_u16: u16, #[bits(12)]
twelve_bits: u16, #[bits(4)]
four_bits: u8, }
assert_eq!(MixedAlignment::field_size(), 6);
let test = MixedAlignment {
regular_u8: 0xFF,
three_bits: 0b111,
five_bits: 0b11111,
regular_u16: 0xABCD,
twelve_bits: 0xFFF,
four_bits: 0xF,
};
let bytes = test.to_be_bytes();
assert_eq!(bytes.len(), 6);
let (parsed, consumed) = MixedAlignment::try_from_be_bytes(&bytes).unwrap();
assert_eq!(parsed, test);
assert_eq!(consumed, 6);
}
#[test]
fn test_zero_values_bit_arithmetic() {
#[derive(BeBytes, Debug, PartialEq)]
struct ZeroTest {
#[bits(3)]
three_bits: u8,
#[bits(5)]
five_bits: u8,
regular: u32,
}
let test = ZeroTest {
three_bits: 0,
five_bits: 0,
regular: 0,
};
assert_eq!(ZeroTest::field_size(), 5);
let bytes = test.to_be_bytes();
assert_eq!(bytes.len(), 5);
assert_eq!(bytes, vec![0, 0, 0, 0, 0]);
}
#[test]
fn test_single_bit_fields() {
#[derive(BeBytes, Debug, PartialEq)]
struct SingleBitFlags {
#[bits(1)]
flag1: u8,
#[bits(1)]
flag2: u8,
#[bits(1)]
flag3: u8,
#[bits(1)]
flag4: u8,
#[bits(1)]
flag5: u8,
#[bits(1)]
flag6: u8,
#[bits(1)]
flag7: u8,
#[bits(1)]
flag8: u8,
}
assert_eq!(SingleBitFlags::field_size(), 1);
let test = SingleBitFlags {
flag1: 1,
flag2: 0,
flag3: 1,
flag4: 0,
flag5: 1,
flag6: 0,
flag7: 1,
flag8: 0,
};
let bytes = test.to_be_bytes();
assert_eq!(bytes.len(), 1);
assert_eq!(bytes[0], 0b10101010);
}
#[test]
fn test_array_field_bit_calculation() {
#[derive(BeBytes, Debug, PartialEq)]
struct ArrayTest {
#[bits(4)]
nibble: u8,
#[bits(4)]
another: u8,
data: [u8; 10], }
assert_eq!(ArrayTest::field_size(), 11);
let test = ArrayTest {
nibble: 0xF,
another: 0xF,
data: [0xAA; 10],
};
let bytes = test.to_be_bytes();
assert_eq!(bytes.len(), 11);
assert_eq!(bytes[0], 0xFF); for &byte in &bytes[1..11] {
assert_eq!(byte, 0xAA);
}
}
#[test]
fn test_enum_bit_field_sizes() {
#[derive(BeBytes, Debug, PartialEq, Copy, Clone)]
enum TestEnum {
A = 0,
B = 1,
C = 2,
D = 3,
}
#[derive(BeBytes, Debug, PartialEq)]
struct EnumTest {
first_enum: TestEnum, #[bits(2)]
two_bits: u8,
#[bits(6)]
six_bits: u8,
second_enum: TestEnum, #[bits(3)]
three_bits: u8,
#[bits(5)]
five_bits: u8,
}
assert_eq!(EnumTest::field_size(), 4);
let test = EnumTest {
first_enum: TestEnum::D,
two_bits: 0b11,
six_bits: 0b111111,
second_enum: TestEnum::C,
three_bits: 0b111,
five_bits: 0b11111,
};
let bytes = test.to_be_bytes();
assert_eq!(bytes.len(), 4);
let (parsed, _) = EnumTest::try_from_be_bytes(&bytes).unwrap();
assert_eq!(parsed, test);
}