oct 0.36.2

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

//! Tests for [`FromOctets`].

#![cfg(test)]

use oct::{FromOctets, IntoOctets};

#[cfg(miri)]
use core::cell::{Cell, UnsafeCell};

#[cfg(miri)]
use core::cmp::Reverse;

#[cfg(miri)]
use core::hint::black_box;

#[cfg(miri)]
use core::marker::{PhantomData, PhantomPinned};

#[cfg(miri)]
use core::mem::{ManuallyDrop, MaybeUninit};

#[cfg(miri)]
use core::num::{NonZero, Saturating, Wrapping};

#[cfg(miri)]
use core::ptr::NonNull;

#[cfg(all(miri, feature = "proc_macro"))]
use oct::Zeroable;

#[cfg(all(miri, target_has_atomic = "128", feature = "atomic_u128_i128"))]
use core::sync::atomic::{AtomicI128, AtomicU128};

#[cfg(all(miri, target_has_atomic = "16"))]
use core::sync::atomic::{AtomicI16, AtomicU16};

#[cfg(all(miri, target_has_atomic = "32"))]
use core::sync::atomic::{AtomicI32, AtomicU32};

#[cfg(all(miri, target_has_atomic = "64"))]
use core::sync::atomic::{AtomicI64, AtomicU64};

#[cfg(all(miri, target_has_atomic = "8"))]
use core::sync::atomic::{AtomicI8, AtomicU8};

#[cfg(miri)]
#[test]
fn test_oned() {
	fn test<T: FromOctets>() {
		fn test<T: FromOctets>() {
			let value = T::new_oned();
			black_box(value);
		}

		test::<T>();
		test::<[T; 00]>();
		test::<[T; 01]>();
		test::<[T; 02]>();
		test::<[T; 03]>();
		test::<[T; 04]>();
		test::<[T; 05]>();
		test::<[T; 06]>();
		test::<[T; 07]>();
		test::<[T; 08]>();
		test::<[T; 09]>();
		test::<[T; 10]>();
		test::<[T; 11]>();
		test::<[T; 12]>();
		test::<[T; 13]>();
		test::<[T; 13]>();
		test::<[T; 14]>();
		test::<[T; 15]>();
		test::<[T; 16]>();
		test::<[T; 17]>();
		test::<[T; 18]>();
		test::<[T; 19]>();
		test::<[T; 20]>();
		test::<[T; 21]>();
		test::<[T; 22]>();
		test::<[T; 23]>();
		test::<[T; 23]>();
		test::<[T; 24]>();
		test::<[T; 25]>();
		test::<[T; 26]>();
		test::<[T; 27]>();
		test::<[T; 28]>();
		test::<[T; 29]>();
		test::<[T; 30]>();
		test::<[T; 31]>();
		test::<[T; 32]>();
		test::<Cell<T>>();
		test::<ManuallyDrop<T>>();
		test::<MaybeUninit<T>>();
		test::<Option<NonNull<T>>>();
		test::<PhantomData<T>>();
		test::<Reverse<T>>();
		test::<Saturating<T>>();
		test::<(T,)>();
		test::<(T, T)>();
		test::<(T, T, T)>();
		test::<(T, T, T, T)>();
		test::<(T, T, T, T, T)>();
		test::<(T, T, T, T, T, T)>();
		test::<(T, T, T, T, T, T, T)>();
		test::<(T, T, T, T, T, T, T, T)>();
		test::<(T, T, T, T, T, T, T, T, T)>();
		test::<(T, T, T, T, T, T, T, T, T, T)>();
		test::<(T, T, T, T, T, T, T, T, T, T, T)>();
		test::<(T, T, T, T, T, T, T, T, T, T, T, T)>();
		test::<UnsafeCell<T>>();
		test::<Wrapping<T>>();
	}

	test::<f32>();
	test::<f64>();
	test::<i128>();
	test::<i16>();
	test::<i32>();
	test::<i64>();
	test::<i8>();
	test::<isize>();
	test::<Option<NonNull<u8>>>();
	test::<Option<NonZero<i128>>>();
	test::<Option<NonZero<i16>>>();
	test::<Option<NonZero<i32>>>();
	test::<Option<NonZero<i64>>>();
	test::<Option<NonZero<i8>>>();
	test::<Option<NonZero<isize>>>();
	test::<Option<NonZero<u128>>>();
	test::<Option<NonZero<u16>>>();
	test::<Option<NonZero<u32>>>();
	test::<Option<NonZero<u64>>>();
	test::<Option<NonZero<u8>>>();
	test::<Option<NonZero<usize>>>();
	test::<PhantomPinned>();
	test::<u128>();
	test::<u16>();
	test::<u32>();
	test::<u64>();
	test::<u8>();
	test::<()>();
	test::<usize>();

	#[cfg(feature = "f128")]
	test::<f128>();

	#[cfg(feature = "f16")]
	test::<f16>();

	#[cfg(all(target_has_atomic = "128", feature = "atomic_u128_i128"))]
	test::<AtomicI128>();

	#[cfg(target_has_atomic = "16")]
	test::<AtomicI16>();

	#[cfg(target_has_atomic = "32")]
	test::<AtomicI32>();

	#[cfg(target_has_atomic = "64")]
	test::<AtomicI64>();

	#[cfg(target_has_atomic = "8")]
	test::<AtomicI8>();

	#[cfg(all(target_has_atomic = "128", feature = "atomic_u128_i128"))]
	test::<AtomicU128>();

	#[cfg(target_has_atomic = "16")]
	test::<AtomicU16>();

	#[cfg(target_has_atomic = "32")]
	test::<AtomicU32>();

	#[cfg(target_has_atomic = "64")]
	test::<AtomicU64>();

	#[cfg(target_has_atomic = "8")]
	test::<AtomicU8>();
}

#[test]
fn test_from_octets_with_len() {
	let octets = u128::MAX.as_octets();

	let len = size_of::<u128>() / size_of::<i16>();

	assert_eq!(
		<[i16]>::ref_from_octets_with_metadata(octets, len),
		&[-1, -1, -1, -1, -1, -1, -1, -1],
	);
}

#[cfg(all(feature = "proc_macro", miri))]
#[test]
#[should_panic]
fn test_read_from_octets_aligned_unaligned() {
	#[repr(align(16), C)]
	#[derive(FromOctets, Zeroable)]
	struct Aligned;

	#[repr(align(16), C)]
	#[derive(Default)]
	struct Octets([u8; 2]);

	let octets = &Octets::default().0[1..];

	let _ = Aligned::read_from_octets(octets);
}

#[cfg(miri)]
#[test]
#[should_panic]
fn test_read_from_octets_unsized() {
	#[repr(align(4), C)]
	#[derive(Default)]
	struct Octets([u8; 3]);

	let octets = &Octets::default().0;

	let _ = i32::read_from_octets(octets);
}