1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
/*
* SPDX-FileCopyrightText: 2023 Tommaso Fontana
* SPDX-FileCopyrightText: 2023 Inria
* SPDX-FileCopyrightText: 2023 Sebastiano Vigna
*
* SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
*/
/// Inner private trait used to make implementing [`Endianness`]
/// impossible for other structs.
mod private {
/// This is a [SealedTrait](https://predr.ag/blog/definitive-guide-to-sealed-traits-in-rust/).
pub trait Endianness: 'static {
/// The name of the endianness.
const _NAME: &'static str;
/// Whether the endianness is little-endian.
const _IS_LITTLE: bool;
/// Whether the endianness is big-endian.
const _IS_BIG: bool;
}
}
impl<T: private::Endianness> Endianness for T {
const NAME: &'static str = T::_NAME;
const IS_LITTLE: bool = T::_IS_LITTLE;
const IS_BIG: bool = T::_IS_BIG;
}
/// Marker trait for endianness selector types.
///
/// Its only implementations are [`LittleEndian`] and [`BigEndian`]
///
/// Note that in principle marker traits are not necessary to use
/// selector types, but they are useful to avoid that the user specifies
/// a nonsensical type, and to document the meaning of type parameters.
pub trait Endianness: private::Endianness {
/// The name of the endianness.
const NAME: &'static str;
/// Whether the endianness is little-endian.
const IS_LITTLE: bool;
/// Whether the endianness is big-endian.
const IS_BIG: bool;
}
impl ToString for LE {
fn to_string(&self) -> String {
LE::NAME.to_string()
}
}
impl ToString for BE {
fn to_string(&self) -> String {
LE::NAME.to_string()
}
}
/// Selector type for little-endian streams.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct LittleEndian;
/// Selector type for big-endian streams.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BigEndian;
impl private::Endianness for LittleEndian {
const _NAME: &'static str = "little";
const _IS_LITTLE: bool = true;
const _IS_BIG: bool = false;
}
impl private::Endianness for BigEndian {
const _NAME: &'static str = "big";
const _IS_LITTLE: bool = false;
const _IS_BIG: bool = true;
}
/// Alias for [`BigEndian`]
pub type BE = BigEndian;
/// Alias for [`LittleEndian`]
pub type LE = LittleEndian;
#[cfg(target_endian = "little")]
/// A type alias for the native endianness of the target platform.
pub type NativeEndian = LittleEndian;
#[cfg(target_endian = "big")]
/// A type alias for the native endianness of the target platform.
pub type NativeEndian = BigEndian;
/// An Alias for [`NativeEndian`]
pub type NE = NativeEndian;