oct 0.26.0

Octonary transcodings.
Documentation
// Copyright 2024-2025 Gabriel Bjørnager Jensen.
//
// This Source Code Form is subject to the terms of
// the Mozilla Public License, v. 2.0. If a copy of
// the MPL was not distributed with this file, you
// can obtain one at:
// <https://mozilla.org/MPL/2.0/>.

//! Tests for [`Deserialise`].

#![cfg(test)]

use core::char;

#[cfg(feature = "proc_macro")]
use oct::io::Deserialise;

macro_rules! test {
	{$( $Ty:ty { $($lhs:expr => $rhs:pat),+$(,)? }$(,)?)*} => {
		$($({
			let mut data: &[u8] = &$lhs;

			let lhs = <$Ty as ::oct::io::Deserialise>::deserialise(&mut data);

			#[allow(clippy::redundant_pattern_matching)]
			if !matches!(lhs, $rhs) {
				::core::panic!(
					"deserialisation test failed: `{lhs:?}` does not match `{}`",
					::core::stringify!($rhs),
				);
			}
		})*)*
	};
}

#[test]
fn test_deserialise() {
	test! {
		i8 {
			[0x00] => Ok(0x00),
			[0x7F] => Ok(0x7F),
			[0x80] => Ok(-0x80),
			[0xFF] => Ok(-0x01),
		}

		i16 {
			[0x00, 0x00] => Ok(0x0000),
			[0xFF, 0x7F] => Ok(0x7FFF),
			[0x00, 0x80] => Ok(-0x8000),
			[0xFF, 0xFF] => Ok(-0x0001),
		}

		i32 {
			[0x00, 0x00, 0x00, 0x00] => Ok(0x00000000),
			[0xFF, 0xFF, 0xFF, 0x7F] => Ok(0x7FFFFFFF),
			[0x00, 0x00, 0x00, 0x80] => Ok(-0x80000000),
			[0xFF, 0xFF, 0xFF, 0xFF] => Ok(-0x00000001),
		}

		i64 {
			[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] => Ok(0x0000000000000000),
			[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F] => Ok(0x7FFFFFFFFFFFFFFF),
			[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80] => Ok(-0x8000000000000000),
			[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF] => Ok(-0x0000000000000001),
		}

		u128 {
			[
				0x7F, 0x8F, 0x6F, 0x9F, 0x5F, 0xAF, 0x4F, 0xBF,
				0x3F, 0xCF, 0x2F, 0xDF, 0x1F, 0xEF, 0x0F, 0xFF,
			] => Ok(0xFF_0F_EF_1F_DF_2F_CF_3F_BF_4F_AF_5F_9F_6F_8F_7F),
		}

		char {
			[0xFD, 0xFF, 0x00, 0x00] => Ok(char::REPLACEMENT_CHARACTER),
		}

		[char; 0x5] {
			[
				0xBB, 0x03, 0x00, 0x00, 0x91, 0x03, 0x00, 0x00,
				0xBC, 0x03, 0x00, 0x00, 0x94, 0x03, 0x00, 0x00,
				0xB1, 0x03, 0x00, 0x00,
			] => Ok(['\u{03BB}', '\u{0391}', '\u{03BC}', '\u{0394}', '\u{03B1}']),
		}

		Option<()> {
			[0x00] => Ok(None),
			[0x01] => Ok(Some(())),
		}

		Result<(), i8> {
			[0x00, 0x00] => Ok(Ok(())),
			[0x01, 0x7F] => Ok(Err(i8::MAX)),
		}
	}
}

#[cfg(feature = "proc_macro")]
#[test]
fn test_derive_decode() {
	#[derive(Debug, Deserialise, PartialEq)]
	struct ProcExit {
		exit_code: i32,
		timestmap: u64,
	}

	#[derive(Debug, Deserialise, PartialEq)]
	struct NewByte(u8);

	#[derive(Debug, Deserialise, PartialEq)]
	struct Unit;

	#[derive(Debug, Deserialise, PartialEq)]
	enum UnitOrFields {
		Unit,
		Unnamed(i32),
		Named { timestamp: u64 },
	}

	test! {
		ProcExit {
			[
				0x01, 0x00, 0x00, 0x00, 0x00, 0xE1, 0x0B, 0x5E,
				0x00, 0x00, 0x00, 0x00,
			] => Ok(ProcExit { exit_code: 0x1, timestmap: 1577836800 }),
		}

		NewByte {
			[0x80] => Ok(NewByte(0x80)),
		}

		Unit {
			[] => Ok(Unit),
		}

		UnitOrFields {
			[
				0x00,
			] => Ok(UnitOrFields::Unit),

			[
				0x01, 0xFF, 0xFF, 0xFF, 0xFF,
			] => Ok(UnitOrFields::Unnamed(-1)),

			[
				0x02, 0x4C, 0xC8, 0xC5, 0x66, 0x00, 0x00, 0x00,
				0x00,
			] => Ok(UnitOrFields::Named { timestamp: 1724237900 }),

			[
				0x03,
			] => Err(..),
		}
	}
}