oct 0.36.2

Octonary transcodings.
Documentation
// Copyright 2024-2026 Gabriel Bjørnager Jensen.
//
// SPDX: MIT OR Apache-2.0

//! Tests for the transmutation functions.

#![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));
}