macro_rules! endian_impl {
($ne_type:ident, $ed_type:ident, $endian:expr, $opposite:expr) => {
#[repr(transparent)]
#[derive(
::zerocopy::Immutable, ::zerocopy::IntoBytes, ::zerocopy::FromBytes, Copy, Clone,
)]
pub struct $ed_type {
v: $ne_type,
}
impl $ed_type {
pub fn to_ne(self) -> $ne_type {
#[cfg(target_endian = $endian)]
{
self.v
}
#[cfg(target_endian = $opposite)]
{
self.v.swap_bytes()
}
}
}
impl From<$ne_type> for $ed_type {
fn from(value: $ne_type) -> Self {
#[cfg(target_endian = $endian)]
{
Self { v: value }
}
#[cfg(target_endian = $opposite)]
{
Self {
v: value.swap_bytes(),
}
}
}
}
impl From<$ed_type> for $ne_type {
fn from(value: $ed_type) -> Self {
#[cfg(target_endian = $endian)]
{
value.v
}
#[cfg(target_endian = $opposite)]
{
value.v.swap_bytes()
}
}
}
impl ::core::fmt::Display for $ed_type {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
#[cfg(target_endian = $endian)]
{
::core::fmt::Display::fmt(&self.v, f)
}
#[cfg(target_endian = $opposite)]
{
::core::fmt::Display::fmt(&self.v.swap_bytes(), f)
}
}
}
impl ::core::fmt::Debug for $ed_type {
fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
f.write_str(stringify!($ed_type))?;
::core::fmt::Write::write_char(f, '(')?;
::core::fmt::Debug::fmt(&self.to_ne(), f)?;
::core::fmt::Write::write_char(f, ')')
}
}
impl From<[u8; ::core::mem::size_of::<$ne_type>()]> for $ed_type {
fn from(value: [u8; ::core::mem::size_of::<$ne_type>()]) -> Self {
Self {
v: $ne_type::from_ne_bytes(value),
}
}
}
};
}
macro_rules! endian_type {
($ne_type:ident, $le_type:ident, $be_type:ident) => {
endian_impl!($ne_type, $le_type, "little", "big");
endian_impl!($ne_type, $be_type, "big", "little");
};
}
endian_type!(u16, Lu16, Bu16);
endian_type!(u32, Lu32, Bu32);
endian_type!(u64, Lu64, Bu64);
#[cfg(test)]
#[path = "endian_test.rs"]
mod tests;