#![cfg(test)]
use core::cell::Cell;
use core::f64;
use core::hint::black_box;
use oct::{
FromOctets,
Immutable,
Init,
transmute,
transmute_mut,
transmute_ref,
Zeroable,
};
#[repr(C, align(4))]
#[derive(Debug, PartialEq)]
struct Foo(u8, u8, u8, u8);
unsafe impl FromOctets for Foo {}
unsafe impl Immutable for Foo {}
unsafe impl Init for Foo {}
unsafe impl Zeroable for Foo {}
#[test]
fn test_transmute() {
assert_eq!(
transmute::<u8, i8>(211),
-45_i8,
);
assert_eq!(
transmute::<i32, Foo>(i32::from_be(0x7F_FF_00_7F)),
Foo(0x7F, 0xFF, 0x00, 0x7F),
);
}
#[test]
fn test_transmute_mut() {
let mut src = [
f64::consts::PI,
f64::consts::TAU,
];
assert_eq!(src.len(), 2);
assert!(!src[0].is_nan());
assert!(!src[1].is_infinite());
assert!(!src[1].is_nan());
let dst: &mut [Cell<u64>] = transmute_mut(&mut src);
assert_eq!(dst.len(), 2);
assert_eq!(dst[0].get(), f64::consts::PI.to_bits());
assert_eq!(dst[1].get(), f64::consts::TAU.to_bits());
dst[0].set(f64::NAN.to_bits());
dst[1].set(f64::INFINITY.to_bits());
assert!(src[0].is_nan());
assert!(src[1].is_infinite());
assert!(!src[1].is_nan());
}
#[test]
fn test_transmute_ref_valid_align() {
#[repr(align(8), C)]
struct Src(pub [u32; 4]);
let src = Src([
u32::from_be(0x00_11_22_33),
u32::from_be(0x44_55_66_77),
u32::from_be(0x88_99_AA_BB),
u32::from_be(0xCC_DD_EE_FF),
]);
assert_eq!(src.0.len(), 4);
let dst: &[u64] = transmute_ref(&src.0);
assert_eq!(dst.len(), 2);
assert_eq!(
dst,
&[
u64::from_be(0x00_11_22_33_44_55_66_77),
u64::from_be(0x88_99_AA_BB_CC_DD_EE_FF),
],
);
}
#[test]
#[should_panic]
fn test_transmute_ref_invalid_align() {
#[repr(align(2), C)]
struct Src {
pub pad: u8,
pub data: [u8; 2],
}
let src = Src {
pad: 0,
data: i16::MAX.to_be_bytes(),
};
assert_eq!(src.data.len(), 2);
let dst: &[i16] = transmute_ref(&src.data);
black_box(dst);
}
#[test]
#[should_panic]
fn test_transmute_ref_invalid_size() {
let src = "EjEjEjEjEjEjEj";
assert_eq!(src.len(), 15);
let dst: &[u128] = transmute_ref(src);
black_box(dst);
}
#[test]
#[should_panic]
fn test_transmute_ref_valid_size() {
let src = "EjEjEjEjEjEjEjE";
assert_eq!(src.len(), 15);
let dst: &[u128] = transmute_ref(src);
assert_eq!(dst[0], u128::from_be(0x45_69_45_69_45_69_45_69_45_69_45_69_45_69_45_69));
}