#[macro_export]
#[doc(hidden)]
macro_rules! __pick {
($($endian:literal $(/ $pointer_width:literal)? => $expr:expr),+ $(, _ => $fallback:expr)? $(,)?) => {
match () {
$(
#[cfg(all(target_endian = $endian $(, target_pointer_width = $pointer_width)*))]
() => $expr,
)*
#[cfg(not(any($(all(target_endian = $endian $(, target_pointer_width = $pointer_width)*)),*)))]
() => $crate::__pick_fallback!($($fallback)*)
}
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! __pick_fallback {
() => {
struct UnsupportedEndian;
UnsupportedEndian
};
($expr:expr) => {
$expr
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! __matches {
($expr:expr, $($endian:literal $(/ $pointer_width:literal)? => $pat:pat_param $(| $pat_second:pat_param)* $(if $cond:expr)?),+ $(,)?) => {
match $expr {
$(
#[cfg(all(target_endian = $endian $(, target_pointer_width = $pointer_width)*))]
$pat $(| $pat_second)* $(if $cond)* => true,
)*
_ => false,
}
};
}
#[doc(inline)]
pub use __pick as pick;
#[doc(inline)]
pub use __matches as matches;
#[doc(inline)]
pub use self::endian::Endian;
mod endian;
#[cfg(target_endian = "little")]
pub type Native = Little;
#[cfg(target_endian = "big")]
pub type Native = Big;
#[cfg(target_endian = "little")]
pub type Other = Big;
#[cfg(target_endian = "big")]
pub type Other = Little;
#[non_exhaustive]
pub struct Big;
#[non_exhaustive]
pub struct Little;
use crate::ZeroCopy;
pub fn from_be<T>(value: T) -> T
where
T: ZeroCopy,
{
from_endian::<_, Big>(value)
}
#[inline]
pub fn from_le<T>(value: T) -> T
where
T: ZeroCopy,
{
from_endian::<_, Little>(value)
}
#[inline]
pub fn from_endian<T, E>(value: T) -> T
where
T: ZeroCopy,
E: ByteOrder,
{
value.swap_bytes::<E>().swap_bytes::<Native>()
}
mod sealed {
use super::{Big, Little};
pub trait Sealed {}
impl Sealed for Big {}
impl Sealed for Little {}
}
pub trait ByteOrder: 'static + Sized + self::sealed::Sealed {
#[doc(hidden)]
fn try_map<T, F>(value: T, map: F) -> T
where
F: FnOnce(T) -> T;
#[doc(hidden)]
fn swap_usize(value: usize) -> usize;
#[doc(hidden)]
fn swap_isize(value: isize) -> isize;
#[doc(hidden)]
fn swap_u16(value: u16) -> u16;
#[doc(hidden)]
fn swap_i16(value: i16) -> i16;
#[doc(hidden)]
fn swap_u32(value: u32) -> u32;
#[doc(hidden)]
fn swap_i32(value: i32) -> i32;
#[doc(hidden)]
fn swap_u64(value: u64) -> u64;
#[doc(hidden)]
fn swap_i64(value: i64) -> i64;
#[doc(hidden)]
fn swap_u128(value: u128) -> u128;
#[doc(hidden)]
fn swap_i128(value: i128) -> i128;
#[doc(hidden)]
fn swap_f32(value: f32) -> f32;
#[doc(hidden)]
fn swap_f64(value: f64) -> f64;
}
impl ByteOrder for Little {
#[cfg(target_endian = "little")]
#[inline(always)]
fn try_map<T, F>(value: T, _: F) -> T
where
F: FnOnce(T) -> T,
{
value
}
#[cfg(not(target_endian = "little"))]
#[inline(always)]
fn try_map<T, F>(value: T, map: F) -> T
where
F: FnOnce(T) -> T,
{
map(value)
}
#[inline]
fn swap_usize(value: usize) -> usize {
usize::from_le(value)
}
#[inline]
fn swap_isize(value: isize) -> isize {
isize::from_le(value)
}
#[inline]
fn swap_u16(value: u16) -> u16 {
u16::to_le(value)
}
#[inline]
fn swap_i16(value: i16) -> i16 {
i16::to_le(value)
}
#[inline]
fn swap_u32(value: u32) -> u32 {
u32::from_le(value)
}
#[inline]
fn swap_i32(value: i32) -> i32 {
i32::from_le(value)
}
#[inline]
fn swap_u64(value: u64) -> u64 {
u64::from_le(value)
}
#[inline]
fn swap_i64(value: i64) -> i64 {
i64::from_le(value)
}
#[inline]
fn swap_u128(value: u128) -> u128 {
u128::from_le(value)
}
#[inline]
fn swap_i128(value: i128) -> i128 {
i128::from_le(value)
}
#[inline]
fn swap_f32(value: f32) -> f32 {
f32::from_bits(u32::from_le(value.to_bits()))
}
#[inline]
fn swap_f64(value: f64) -> f64 {
f64::from_bits(u64::from_le(value.to_bits()))
}
}
impl ByteOrder for Big {
#[cfg(target_endian = "big")]
#[inline(always)]
fn try_map<T, F>(value: T, _: F) -> T
where
F: FnOnce(T) -> T,
{
value
}
#[cfg(not(target_endian = "big"))]
#[inline(always)]
fn try_map<T, F>(value: T, map: F) -> T
where
F: FnOnce(T) -> T,
{
map(value)
}
#[inline]
fn swap_usize(value: usize) -> usize {
usize::from_be(value)
}
#[inline]
fn swap_isize(value: isize) -> isize {
isize::from_be(value)
}
#[inline]
fn swap_u16(value: u16) -> u16 {
u16::to_be(value)
}
#[inline]
fn swap_i16(value: i16) -> i16 {
i16::to_be(value)
}
#[inline]
fn swap_u32(value: u32) -> u32 {
u32::from_be(value)
}
#[inline]
fn swap_i32(value: i32) -> i32 {
i32::from_be(value)
}
#[inline]
fn swap_u64(value: u64) -> u64 {
u64::from_be(value)
}
#[inline]
fn swap_i64(value: i64) -> i64 {
i64::from_be(value)
}
#[inline]
fn swap_u128(value: u128) -> u128 {
u128::from_be(value)
}
#[inline]
fn swap_i128(value: i128) -> i128 {
i128::from_be(value)
}
#[inline]
fn swap_f32(value: f32) -> f32 {
f32::from_bits(u32::from_be(value.to_bits()))
}
#[inline]
fn swap_f64(value: f64) -> f64 {
f64::from_bits(u64::from_be(value.to_bits()))
}
}