pub unsafe trait Endian: Clone {
fn convert_u16(&self, bytes: [u8; 2]) -> u16;
fn convert_u32(&self, bytes: [u8; 4]) -> u32;
fn convert_u64(&self, bytes: [u8; 8]) -> u64;
fn is_native(&self) -> bool {
false
}
}
#[derive(Copy, Clone, Debug, Default)]
pub struct Native;
unsafe impl Endian for Native {
#[inline]
fn convert_u16(&self, bytes: [u8; 2]) -> u16 {
u16::from_ne_bytes(bytes)
}
#[inline]
fn convert_u32(&self, bytes: [u8; 4]) -> u32 {
u32::from_ne_bytes(bytes)
}
#[inline]
fn convert_u64(&self, bytes: [u8; 8]) -> u64 {
u64::from_ne_bytes(bytes)
}
#[inline]
fn is_native(&self) -> bool {
true
}
}
#[derive(Copy, Clone, Debug, Default)]
pub struct Little;
unsafe impl Endian for Little {
#[inline]
fn convert_u16(&self, bytes: [u8; 2]) -> u16 {
u16::from_le_bytes(bytes)
}
#[inline]
fn convert_u32(&self, bytes: [u8; 4]) -> u32 {
u32::from_le_bytes(bytes)
}
#[inline]
fn convert_u64(&self, bytes: [u8; 8]) -> u64 {
u64::from_le_bytes(bytes)
}
#[inline]
fn is_native(&self) -> bool {
let bytes = [b'a', b'b'];
u16::from_le_bytes(bytes) == u16::from_ne_bytes(bytes)
}
}
#[derive(Copy, Clone, Debug, Default)]
pub struct Big;
unsafe impl Endian for Big {
#[inline]
fn convert_u16(&self, bytes: [u8; 2]) -> u16 {
u16::from_be_bytes(bytes)
}
#[inline]
fn convert_u32(&self, bytes: [u8; 4]) -> u32 {
u32::from_be_bytes(bytes)
}
#[inline]
fn convert_u64(&self, bytes: [u8; 8]) -> u64 {
u64::from_be_bytes(bytes)
}
#[inline]
fn is_native(&self) -> bool {
let bytes = [b'a', b'b'];
u16::from_be_bytes(bytes) == u16::from_ne_bytes(bytes)
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub enum Dynamic {
Big,
Little,
}
unsafe impl Endian for Dynamic {
fn convert_u16(&self, bytes: [u8; 2]) -> u16 {
match self {
Self::Big => Big.convert_u16(bytes),
Self::Little => Little.convert_u16(bytes),
}
}
fn convert_u32(&self, bytes: [u8; 4]) -> u32 {
match self {
Self::Big => Big.convert_u32(bytes),
Self::Little => Little.convert_u32(bytes),
}
}
fn convert_u64(&self, bytes: [u8; 8]) -> u64 {
match self {
Self::Big => Big.convert_u64(bytes),
Self::Little => Little.convert_u64(bytes),
}
}
fn is_native(&self) -> bool {
match self {
Self::Big => Big.is_native(),
Self::Little => Little.is_native(),
}
}
}