array-fusion 0.2.0

Array merging and splitting facilities
Documentation
//! Byte oriented array utils.
//!
//! This module provides various utilities to encode and decode byte-aware
//! date types from and into arrays.
//!
//! Also see the [`encoding`] sub-module for converting data types into byte
//! arrays, and [`decoding`] sub-module for converting byte arrays into data
//! types.
//!


use hybrid_array::AssocArraySize;
use hybrid_array::sizes::U1;
use hybrid_array::sizes::U2;
use hybrid_array::sizes::U4;
use hybrid_array::sizes::U8;
use hybrid_array::sizes::U16;



pub mod decoding;
pub mod encoding;



type SizeOf<T, const N: usize> = <[T; N] as AssocArraySize>::Size;



macro_rules! impl_from_bytes_for_int_wrapper {
	{
		wrapper: $name:ident;
		conv_method: $conv_method:ident;
		ints: $( ( $int:ident , $size:ident ) ),* $(,)? $(;)?
	} => {
		$(
			impl $crate::bytes::decoding::FromByteArray for $name<$int> {
				type Size = $size;

				fn from_bytes(array: $crate::Array<u8, Self::Size>) -> Self {
					$name($int::$conv_method(array.0))
				}
			}
		)*
	};
}

macro_rules! impl_into_bytes_for_int_wrapper {
	{
		wrapper: $name:ident;
		conv_method: $conv_method:ident;
		ints: $( ( $int:ident , $size:ident ) ),* $(,)? $(;)?
	} => {
		$(
			impl $crate::bytes::encoding::IntoByteArray for $name<$int> {
				type Size = $size;

				fn into_bytes(self) -> $crate::Array<u8, Self::Size> {
					let value = self.0;
					$crate::Array(value.$conv_method())
				}
			}
		)*
	};
}


pub type Be<T> = BigEndian<T>;
pub type Net<T> = BigEndian<T>;

/// A wrapper type for big-endian integer parsing.
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct BigEndian<T>(pub T);

impl_from_bytes_for_int_wrapper! {
	wrapper: BigEndian;
	conv_method: from_be_bytes;
	ints:
		(u8, U1),
		(u16, U2),
		(u32, U4),
		(u64, U8),
		(u128, U16),
		(i8, U1),
		(i16, U2),
		(i32, U4),
		(i64, U8),
		(i128, U16),
		(f32, U4),
		(f64, U8),
}
impl_into_bytes_for_int_wrapper! {
	wrapper: BigEndian;
	conv_method: to_be_bytes;
	ints:
		(u8, U1),
		(u16, U2),
		(u32, U4),
		(u64, U8),
		(u128, U16),
		(i8, U1),
		(i16, U2),
		(i32, U4),
		(i64, U8),
		(i128, U16),
		(f32, U4),
		(f64, U8),
}

pub type Le<T> = LittleEndian<T>;

/// A wrapper type for little-endian integer parsing.
///
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct LittleEndian<T>(pub T);

impl_from_bytes_for_int_wrapper! {
	wrapper: LittleEndian;
	conv_method: from_le_bytes;
	ints:
		(u8, U1),
		(u16, U2),
		(u32, U4),
		(u64, U8),
		(u128, U16),
		(i8, U1),
		(i16, U2),
		(i32, U4),
		(i64, U8),
		(i128, U16),
		(f32, U4),
		(f64, U8),
}
impl_into_bytes_for_int_wrapper! {
	wrapper: LittleEndian;
	conv_method: to_le_bytes;
	ints:
		(u8, U1),
		(u16, U2),
		(u32, U4),
		(u64, U8),
		(u128, U16),
		(i8, U1),
		(i16, U2),
		(i32, U4),
		(i64, U8),
		(i128, U16),
		(f32, U4),
		(f64, U8),
}

pub type Ne<T> = NativeEndian<T>;

/// A wrapper type for native-endian integer parsing.
///
/// Notice that this encoding is not portable across different platforms with
/// different endianness. Thus this wrapper should not be used for data that
/// needs to be shared across different platforms.
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct NativeEndian<T>(pub T);

impl_from_bytes_for_int_wrapper! {
	wrapper: NativeEndian;
	conv_method: from_ne_bytes;
	ints:
		(u8, U1),
		(u16, U2),
		(u32, U4),
		(u64, U8),
		(u128, U16),
		(i8, U1),
		(i16, U2),
		(i32, U4),
		(i64, U8),
		(i128, U16),
		(f32, U4),
		(f64, U8),
}
impl_into_bytes_for_int_wrapper! {
	wrapper: NativeEndian;
	conv_method: to_ne_bytes;
	ints:
		(u8, U1),
		(u16, U2),
		(u32, U4),
		(u64, U8),
		(u128, U16),
		(i8, U1),
		(i16, U2),
		(i32, U4),
		(i64, U8),
		(i128, U16),
		(f32, U4),
		(f64, U8),
}