use fixed_bigint::num_traits::{self, FromPrimitive};
use fixed_bigint::FixedUInt;
#[test]
fn test_from_le_bytes() {
type TestInt = FixedUInt<u16, 2>;
let empty_bytes = [];
let result = TestInt::from_le_bytes(&empty_bytes);
assert_eq!(result, TestInt::from(0u8));
let single_byte = [0x42];
let result = TestInt::from_le_bytes(&single_byte);
assert_eq!(result, TestInt::from(0x42u8));
let two_bytes = [0x34, 0x12];
let result = TestInt::from_le_bytes(&two_bytes);
assert_eq!(result, TestInt::from(0x1234u16));
let word_size_bytes = [0x78, 0x56, 0x34, 0x12];
let result = TestInt::from_le_bytes(&word_size_bytes);
let expected = TestInt::from(0x5678u16) + (TestInt::from(0x1234u16) << 16u32);
assert_eq!(result, expected);
let more_bytes = [0x00, 0x00, 0x78, 0x56, 0x34, 0x12];
let result = TestInt::from_le_bytes(&more_bytes);
let expected = TestInt::from(0x0000u16) + (TestInt::from(0x5678u16) << 16u32);
assert_eq!(result, expected);
}
#[test]
fn test_from_be_bytes() {
type TestInt = FixedUInt<u16, 2>;
let empty_bytes = [];
let result = TestInt::from_be_bytes(&empty_bytes);
assert_eq!(result, TestInt::from(0u8));
let single_byte = [0x42];
let result = TestInt::from_be_bytes(&single_byte);
assert_eq!(result, TestInt::from(0x42u8));
let two_bytes = [0x12, 0x34];
let result = TestInt::from_be_bytes(&two_bytes);
assert_eq!(result, TestInt::from(0x1234u16));
let word_size_bytes = [0x12, 0x34, 0x56, 0x78];
let result = TestInt::from_be_bytes(&word_size_bytes);
assert_eq!(result, TestInt::from(0x12345678u32));
let more_bytes = [0x12, 0x34, 0x56, 0x78, 0x00, 0x00];
let result = TestInt::from_be_bytes(&more_bytes);
assert_eq!(result, TestInt::from(0x56780000u32));
let multi_word_bytes = [0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88];
let result = TestInt::from_be_bytes(&multi_word_bytes);
assert_eq!(result, TestInt::from(0x55667788u32));
}
#[test]
fn test_consistent_truncation_behavior() {
type TestInt = FixedUInt<u16, 2>;
let long_bytes = [0x11, 0x22, 0x33, 0x44, 0x55, 0x66];
let le_result = TestInt::from_le_bytes(&long_bytes);
let be_result = TestInt::from_be_bytes(&long_bytes);
assert_eq!(le_result, TestInt::from_le_bytes(&[0x11, 0x22, 0x33, 0x44]));
assert_eq!(be_result, TestInt::from_be_bytes(&[0x33, 0x44, 0x55, 0x66]));
let exact_bytes = [0xAA, 0xBB, 0xCC, 0xDD];
let le_exact = TestInt::from_le_bytes(&exact_bytes);
let be_exact = TestInt::from_be_bytes(&exact_bytes);
assert_eq!(le_exact, TestInt::from(0xDDCCBBAAu32));
assert_eq!(be_exact, TestInt::from(0xAABBCCDDu32));
let mut le_buf = [0u8; 4];
le_exact.to_le_bytes(&mut le_buf).unwrap();
assert_eq!(le_buf, [0xAA, 0xBB, 0xCC, 0xDD]);
let mut be_buf = [0u8; 4];
be_exact.to_be_bytes(&mut be_buf).unwrap();
assert_eq!(be_buf, [0xAA, 0xBB, 0xCC, 0xDD]);
}
#[test]
fn test_to_le_bytes() {
type TestInt = FixedUInt<u16, 2>;
let zero = TestInt::from(0u8);
let mut buffer = [0u8; 8];
let result = zero.to_le_bytes(&mut buffer);
assert!(result.is_ok());
let bytes = result.unwrap();
assert_eq!(bytes, &[0, 0, 0, 0]);
let small = TestInt::from(0x1234u16);
let mut buffer = [0u8; 8];
let result = small.to_le_bytes(&mut buffer);
assert!(result.is_ok());
let bytes = result.unwrap();
assert_eq!(bytes, &[0x34, 0x12, 0, 0]);
let large = TestInt::from(0x12345678u32);
let mut buffer = [0u8; 8];
let result = large.to_le_bytes(&mut buffer);
assert!(result.is_ok());
let bytes = result.unwrap();
assert_eq!(bytes, &[0x78, 0x56, 0x34, 0x12]);
let value = TestInt::from(0x1234u16);
let mut small_buffer = [0u8; 2];
let result = value.to_le_bytes(&mut small_buffer);
assert!(result.is_err());
}
#[test]
fn test_to_be_bytes() {
type TestInt = FixedUInt<u16, 2>;
let zero = TestInt::from(0u8);
let mut buffer = [0u8; 8];
let result = zero.to_be_bytes(&mut buffer);
assert!(result.is_ok());
let bytes = result.unwrap();
assert_eq!(bytes, &[0, 0, 0, 0]);
let small = TestInt::from(0x1234u16);
let mut buffer = [0u8; 8];
let result = small.to_be_bytes(&mut buffer);
assert!(result.is_ok());
let bytes = result.unwrap();
assert_eq!(bytes, &[0, 0, 0x12, 0x34]);
let large = TestInt::from(0x12345678u32);
let mut buffer = [0u8; 8];
let result = large.to_be_bytes(&mut buffer);
assert!(result.is_ok());
let bytes = result.unwrap();
assert_eq!(bytes, &[0x12, 0x34, 0x56, 0x78]);
let value = TestInt::from(0x1234u16);
let mut small_buffer = [0u8; 2];
let result = value.to_be_bytes(&mut small_buffer);
assert!(result.is_err());
let value = TestInt::from(0x1234u16);
let mut buffer = [0xFFu8; 8]; let result = value.to_be_bytes(&mut buffer);
assert!(result.is_ok());
let bytes = result.unwrap();
assert_eq!(bytes[0], 0);
assert_eq!(bytes[1], 0);
assert_eq!(bytes[2], 0x12);
assert_eq!(bytes[3], 0x34);
}
#[test]
fn test_to_hex_str_edge_cases() {
type TestInt = FixedUInt<u16, 2>;
let zero = TestInt::from(0u8);
let mut buffer = [0u8; 10];
let result = zero.to_hex_str(&mut buffer);
assert!(result.is_ok());
assert_eq!(result.unwrap(), "0");
let value = TestInt::from(0x123456u32);
let mut small_buffer = [0u8; 3];
let result = value.to_hex_str(&mut small_buffer);
assert!(result.is_err());
let value = TestInt::from(0x0012u16);
let mut buffer = [0u8; 10];
let result = value.to_hex_str(&mut buffer);
assert!(result.is_ok());
assert_eq!(result.unwrap(), "12");
let max_value = TestInt::from(0xFFFFFFFFu32);
let mut buffer = [0u8; 10];
let result = max_value.to_hex_str(&mut buffer);
assert!(result.is_ok());
assert_eq!(result.unwrap(), "ffffffff");
let value = TestInt::from(0x12u8);
let mut buffer = [0xAAu8; 10]; let result = value.to_hex_str(&mut buffer);
assert!(result.is_ok());
assert_eq!(result.unwrap(), "12");
let value = TestInt::from(0x00000000u32);
let mut buffer = [0u8; 10];
let result = value.to_hex_str(&mut buffer);
assert!(result.is_ok());
assert_eq!(result.unwrap(), "0");
}
#[test]
fn test_to_radix_str_edge_cases() {
type TestInt = FixedUInt<u16, 2>;
let zero = TestInt::from(0u8);
let mut buffer = [0u8; 20];
for radix in [2, 8, 10, 16] {
let result = zero.to_radix_str(&mut buffer, radix);
assert!(result.is_ok());
assert_eq!(result.unwrap(), "0");
}
let value = TestInt::from(123456u32);
let mut small_buffer = [0u8; 3];
let result = value.to_radix_str(&mut small_buffer, 10);
assert!(result.is_err());
let value = TestInt::from(255u8);
let mut buffer = [0u8; 20];
let result = value.to_radix_str(&mut buffer, 2);
assert!(result.is_ok());
assert_eq!(result.unwrap(), "11111111");
let result = value.to_radix_str(&mut buffer, 8);
assert!(result.is_ok());
assert_eq!(result.unwrap(), "377");
let result = value.to_radix_str(&mut buffer, 16);
assert!(result.is_ok());
assert_eq!(result.unwrap(), "ff");
}
#[test]
fn test_bit_length() {
type TestInt = FixedUInt<u16, 2>;
let zero = TestInt::from(0u8);
assert_eq!(zero.bit_length(), 0);
let one = TestInt::from(1u8);
assert_eq!(one.bit_length(), 1);
let two = TestInt::from(2u8);
assert_eq!(two.bit_length(), 2);
let four = TestInt::from(4u8);
assert_eq!(four.bit_length(), 3);
let three = TestInt::from(3u8);
assert_eq!(three.bit_length(), 2);
let fifteen = TestInt::from(15u8);
assert_eq!(fifteen.bit_length(), 4);
let large = TestInt::from(0xFFFFu16);
assert_eq!(large.bit_length(), 16);
let max = TestInt::from(0xFFFFFFFFu32);
assert_eq!(max.bit_length(), 32);
}
#[test]
fn test_div_rem() {
type TestInt = FixedUInt<u16, 2>;
let dividend = TestInt::from(20u8);
let divisor = TestInt::from(3u8);
let (quotient, remainder) = dividend.div_rem(&divisor);
assert_eq!(quotient, TestInt::from(6u8));
assert_eq!(remainder, TestInt::from(2u8));
let dividend = TestInt::from(21u8);
let divisor = TestInt::from(3u8);
let (quotient, remainder) = dividend.div_rem(&divisor);
assert_eq!(quotient, TestInt::from(7u8));
assert_eq!(remainder, TestInt::from(0u8));
let dividend = TestInt::from(42u8);
let divisor = TestInt::from(1u8);
let (quotient, remainder) = dividend.div_rem(&divisor);
assert_eq!(quotient, TestInt::from(42u8));
assert_eq!(remainder, TestInt::from(0u8));
let dividend = TestInt::from(1000u16);
let divisor = TestInt::from(13u8);
let (quotient, remainder) = dividend.div_rem(&divisor);
assert_eq!(quotient, TestInt::from(76u8));
assert_eq!(remainder, TestInt::from(12u8));
}
#[test]
fn test_new() {
type TestInt = FixedUInt<u32, 4>;
let zero = TestInt::new();
assert_eq!(zero, TestInt::from(0u8));
let zero_u8 = FixedUInt::<u8, 8>::new();
assert_eq!(zero_u8, FixedUInt::<u8, 8>::from(0u8));
let zero_u16 = FixedUInt::<u16, 4>::new();
assert_eq!(zero_u16, FixedUInt::<u16, 4>::from(0u8));
let zero_u64 = FixedUInt::<u64, 2>::new();
assert_eq!(zero_u64, FixedUInt::<u64, 2>::from(0u8));
}
#[test]
fn test_hex_fmt_functionality() {
use fixed_bigint::FixedUInt;
let value = FixedUInt::<u16, 2>::from(0x1234u16);
let mut buffer = [0u8; 20];
let result = value.to_hex_str(&mut buffer);
assert!(result.is_ok());
assert_eq!(result.unwrap(), "1234");
let zero = FixedUInt::<u16, 2>::from(0u8);
let mut buffer = [0u8; 20];
let result = zero.to_hex_str(&mut buffer);
assert!(result.is_ok());
assert_eq!(result.unwrap(), "0");
let value = FixedUInt::<u16, 2>::from(0x123456u32);
let mut small_buffer = [0u8; 2];
let result = value.to_hex_str(&mut small_buffer);
assert!(result.is_err());
}
#[test]
fn test_error_conditions() {
type TestInt = FixedUInt<u8, 2>;
let value = TestInt::from(0xFFu8);
let mut buffer = [0u8; 1];
let result = value.to_hex_str(&mut buffer);
assert!(result.is_err());
let value = TestInt::from(255u8);
let mut buffer = [0u8; 2];
let result = value.to_radix_str(&mut buffer, 2);
assert!(result.is_err());
}
#[test]
fn test_internal_byte_logic() {
type TestInt = FixedUInt<u8, 1>;
let bytes = [0x42];
let result = TestInt::from_le_bytes(&bytes);
assert_eq!(result, TestInt::from(0x42u8));
let bytes = [0x42];
let result = TestInt::from_be_bytes(&bytes);
assert_eq!(result, TestInt::from(0x42u8));
let value = TestInt::from(0x42u8);
let mut buffer = [0u8; 4];
let result = value.to_le_bytes(&mut buffer);
assert!(result.is_ok());
let bytes = result.unwrap();
assert_eq!(bytes, &[0x42]);
let value = TestInt::from(0x42u8);
let mut buffer = [0u8; 4];
let result = value.to_be_bytes(&mut buffer);
assert!(result.is_ok());
let bytes = result.unwrap();
assert_eq!(bytes, &[0x42]);
}
#[test]
fn test_string_conversion_edge_cases() {
type TestInt = FixedUInt<u32, 1>;
let value = TestInt::from(0x0123u16);
let mut buffer = [0u8; 10];
let result = value.to_hex_str(&mut buffer);
assert!(result.is_ok());
let result_str = result.unwrap();
assert!(result_str == "123" || result_str == "0");
let value = TestInt::from(15u8);
let mut buffer = [0u8; 10];
let result = value.to_radix_str(&mut buffer, 2);
assert!(result.is_ok());
assert_eq!(result.unwrap(), "1111");
let result = value.to_radix_str(&mut buffer, 8);
assert!(result.is_ok());
assert_eq!(result.unwrap(), "17");
let result = value.to_radix_str(&mut buffer, 16);
assert!(result.is_ok());
assert_eq!(result.unwrap(), "f");
}
#[test]
fn test_from_u64_overflow() {
type Small = FixedUInt<u8, 1>;
assert_eq!(Small::from_u64(255), Some(Small::from(255u8)));
assert_eq!(Small::from_u64(256), None);
type Medium = FixedUInt<u8, 2>; assert_eq!(Medium::from_u64(65535), Some(Medium::from(65535u16)));
assert_eq!(Medium::from_u64(65536), None);
}
#[test]
fn test_numcast_overflow() {
type Small = FixedUInt<u8, 1>;
assert_eq!(num_traits::cast::<u32, Small>(300u32), None);
assert_eq!(
num_traits::cast::<u32, Small>(123u32),
Some(Small::from(123u8))
);
}