Skip to main content

dsi_bitstream/traits/
endianness.rs

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