#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum Endian {
LittleEndian,
BigEndian,
NativeEndian,
}
impl Endian {
pub(crate) fn read_u32(self, buffer: &[u8]) -> u32 {
let buffer = buffer[0..4].try_into().unwrap();
match self {
Self::LittleEndian => u32::from_le_bytes(buffer),
Self::BigEndian => u32::from_be_bytes(buffer),
Self::NativeEndian => u32::from_ne_bytes(buffer),
}
}
pub(crate) fn write_u32(self, buffer: &mut [u8], value: u32) {
let bytes = match self {
Self::LittleEndian => value.to_le_bytes(),
Self::BigEndian => value.to_be_bytes(),
Self::NativeEndian => value.to_ne_bytes(),
};
buffer[0..4].copy_from_slice(&bytes);
}
pub(crate) fn read_i32(self, buffer: &[u8]) -> i32 {
let buffer = buffer[0..4].try_into().unwrap();
match self {
Self::LittleEndian => i32::from_le_bytes(buffer),
Self::BigEndian => i32::from_be_bytes(buffer),
Self::NativeEndian => i32::from_ne_bytes(buffer),
}
}
pub(crate) fn write_i32(self, buffer: &mut [u8], value: i32) {
let bytes = match self {
Self::LittleEndian => value.to_le_bytes(),
Self::BigEndian => value.to_be_bytes(),
Self::NativeEndian => value.to_ne_bytes(),
};
buffer[0..4].copy_from_slice(&bytes);
}
}
#[cfg(test)]
mod test {
use super::Endian;
use assert2::assert;
#[test]
fn write_u32_litte_endian_works() {
let mut buffer = [0u8; 4];
Endian::LittleEndian.write_u32(&mut buffer, 0x01020304);
assert!(buffer == [0x04, 0x03, 0x02, 0x01]);
}
#[test]
fn write_u32_big_endian_works() {
let mut buffer = [0u8; 4];
Endian::BigEndian.write_u32(&mut buffer, 0x01020304);
assert!(buffer == [0x01, 0x02, 0x03, 0x04]);
}
#[test]
fn write_u32_native_endian_works() {
let mut buffer = [0u8; 4];
Endian::LittleEndian.write_u32(&mut buffer, 0x01020304);
#[cfg(target_endian = "little")]
assert!(buffer == [0x04, 0x03, 0x02, 0x01]);
#[cfg(target_endian = "big")]
assert!(buffer == [0x01, 0x02, 0x03, 0x04]);
}
#[test]
fn read_u32_litte_endian_works() {
assert!(Endian::LittleEndian.read_u32(&[0x04, 0x03, 0x02, 0x01]) == 0x01020304);
}
#[test]
fn read_u32_big_endian_works() {
assert!(Endian::BigEndian.read_u32(&[0x01, 0x02, 0x03, 0x04]) == 0x01020304);
}
#[test]
fn read_u32_native_endian_works() {
#[cfg(target_endian = "little")]
assert!(Endian::NativeEndian.read_u32(&[0x04, 0x03, 0x02, 0x01]) == 0x01020304);
#[cfg(target_endian = "big")]
assert!(Endian::NativeEndian.read_u32(&[0x01, 0x02, 0x03, 0x04]) == 0x01020304);
}
#[test]
fn write_i32_litte_endian_works() {
let mut buffer = [0u8; 4];
Endian::LittleEndian.write_i32(&mut buffer, 0x01020304);
assert!(buffer == [0x04, 0x03, 0x02, 0x01]);
Endian::LittleEndian.write_i32(&mut buffer, -0x7efdfcfb);
assert!(buffer == [0x05, 0x03, 0x02, 0x81]);
}
#[test]
fn write_i32_big_endian_works() {
let mut buffer = [0u8; 4];
Endian::BigEndian.write_i32(&mut buffer, 0x01020304);
assert!(buffer == [0x01, 0x02, 0x03, 0x04]);
Endian::BigEndian.write_i32(&mut buffer, -0x7efdfcfb);
assert!(buffer == [0x81, 0x02, 0x03, 0x05]);
}
#[test]
fn write_i32_native_endian_works() {
let mut buffer = [0u8; 4];
Endian::NativeEndian.write_i32(&mut buffer, 0x01020304);
#[cfg(target_endian = "little")]
assert!(buffer == [0x04, 0x03, 0x02, 0x01]);
#[cfg(target_endian = "big")]
assert!(buffer == [0x01, 0x02, 0x03, 0x04]);
Endian::NativeEndian.write_i32(&mut buffer, -0x7efdfcfb);
#[cfg(target_endian = "little")]
assert!(buffer == [0x05, 0x03, 0x02, 0x81]);
#[cfg(target_endian = "big")]
assert!(buffer == [0x81, 0x02, 0x03, 0x05]);
}
#[test]
fn read_i32_litte_endian_works() {
assert!(Endian::LittleEndian.read_i32(&[0x04, 0x03, 0x02, 0x01]) == 0x01020304);
assert!(Endian::LittleEndian.read_i32(&[0x05, 0x03, 0x02, 0x81]) == -0x7efdfcfb);
}
#[test]
fn read_i32_big_endian_works() {
assert!(Endian::BigEndian.read_i32(&[0x01, 0x02, 0x03, 0x04]) == 0x01020304);
assert!(Endian::BigEndian.read_i32(&[0x81, 0x02, 0x03, 0x05]) == -0x7efdfcfb);
}
#[test]
fn read_i32_native_endian_works() {
#[cfg(target_endian = "little")]
assert!(Endian::NativeEndian.read_i32(&[0x04, 0x03, 0x02, 0x01]) == 0x01020304);
#[cfg(target_endian = "little")]
assert!(Endian::NativeEndian.read_i32(&[0x05, 0x03, 0x02, 0x81]) == -0x7efdfcfb);
#[cfg(target_endian = "big")]
assert!(Endian::NativeEndian.read_i32(&[0x01, 0x02, 0x03, 0x04]) == 0x01020304);
#[cfg(target_endian = "big")]
assert!(Endian::NativeEndian.read_i32(&[0x81, 0x02, 0x03, 0x05]) == -0x7efdfcfb);
}
}