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