futures_byteorder/traits.rs
1use std::borrow::{Borrow, BorrowMut};
2
3use crate::{BigEndian, LittleEndian};
4
5pub trait Sealed {}
6
7pub trait ByteArray: Sealed + Default + Borrow<[u8]> + BorrowMut<[u8]> + Copy {}
8
9/// A trait defining byte order conversion behavior.
10///
11/// This trait is implemented by [`BigEndian`], [`LittleEndian`], and their type aliases
12/// to define how numeric values should be converted to and from byte representations.
13///
14/// # Examples
15///
16/// ```
17/// use futures_byteorder::{Endianness, BigEndian, Representable};
18///
19/// let value: u16 = 0x1234;
20/// let bytes = BigEndian::from_representable(&value);
21/// assert_eq!(bytes, [0x12, 0x34]);
22///
23/// let decoded = BigEndian::to_representable::<u16>(&bytes);
24/// assert_eq!(decoded, 0x1234);
25/// ```
26pub trait Endianness: Sealed {
27 /// Converts a representable value to its byte representation using this endianness.
28 ///
29 /// # Examples
30 ///
31 /// ```
32 /// use futures_byteorder::{Endianness, LittleEndian};
33 ///
34 /// let value: u32 = 0x12345678;
35 /// let bytes = LittleEndian::from_representable(&value);
36 /// assert_eq!(bytes, [0x78, 0x56, 0x34, 0x12]);
37 /// ```
38 fn from_representable<R: Representable>(representable: &R) -> R::Representation;
39
40 /// Converts a byte representation to a representable value using this endianness.
41 ///
42 /// # Examples
43 ///
44 /// ```
45 /// use futures_byteorder::{Endianness, BigEndian};
46 ///
47 /// let bytes = [0x12, 0x34, 0x56, 0x78];
48 /// let value = BigEndian::to_representable::<u32>(&bytes);
49 /// assert_eq!(value, 0x12345678);
50 /// ```
51 fn to_representable<R: Representable>(representation: &R::Representation) -> R;
52}
53
54/// A trait for types that can be represented as a fixed-size byte array.
55///
56/// This trait is implemented for all primitive integer types (`u8`-`u128`, `i8`-`i128`)
57/// and floating-point types (`f32`, `f64`). It provides methods for converting between
58/// the type and its byte representation in both little-endian and big-endian formats.
59///
60/// # Examples
61///
62/// ```
63/// use futures_byteorder::Representable;
64///
65/// let value: u16 = 0x1234;
66/// let le_bytes = value.to_le_bytes();
67/// let be_bytes = value.to_be_bytes();
68///
69/// assert_eq!(le_bytes, [0x34, 0x12]);
70/// assert_eq!(be_bytes, [0x12, 0x34]);
71///
72/// assert_eq!(u16::from_le_bytes(le_bytes), value);
73/// assert_eq!(u16::from_be_bytes(be_bytes), value);
74/// ```
75pub trait Representable {
76 /// The byte array type that represents this type.
77 ///
78 /// For example, `u16::Representation` is `[u8; 2]`, and `u64::Representation` is `[u8; 8]`.
79 type Representation: ByteArray;
80
81 /// Creates a value from its little-endian byte representation.
82 fn from_le_bytes(bytes: &Self::Representation) -> Self;
83
84 /// Creates a value from its big-endian byte representation
85 fn from_be_bytes(bytes: &Self::Representation) -> Self;
86
87 /// Returns the little-endian byte representation of this value.
88 fn to_le_bytes(&self) -> Self::Representation;
89
90 /// Returns the big-endian byte representation of this value.
91 fn to_be_bytes(&self) -> Self::Representation;
92}
93
94impl<const N: usize> Sealed for [u8; N] {}
95impl<const N: usize> ByteArray for [u8; N] where [u8; N]: Default + Borrow<[u8]> + BorrowMut<[u8]> {}
96
97impl Sealed for BigEndian {}
98impl Endianness for BigEndian {
99 fn from_representable<R: Representable>(representable: &R) -> R::Representation {
100 representable.to_be_bytes()
101 }
102
103 fn to_representable<R: Representable>(representation: &R::Representation) -> R {
104 R::from_be_bytes(representation)
105 }
106}
107
108impl Sealed for LittleEndian {}
109impl Endianness for LittleEndian {
110 fn from_representable<R: Representable>(representable: &R) -> R::Representation {
111 representable.to_le_bytes()
112 }
113
114 fn to_representable<R: Representable>(representation: &R::Representation) -> R {
115 R::from_le_bytes(representation)
116 }
117}
118
119macro_rules! impl_representable {
120 ($($num:ty),* $(,)?) => {
121 $(impl Representable for $num {
122 type Representation = [u8; std::mem::size_of::<$num>()];
123
124 fn from_le_bytes(bytes: &Self::Representation) -> Self {
125 Self::from_le_bytes(*bytes)
126 }
127
128 fn from_be_bytes(bytes: &Self::Representation) -> Self {
129 Self::from_be_bytes(*bytes)
130 }
131
132 fn to_le_bytes(&self) -> Self::Representation {
133 Self::to_le_bytes(*self)
134 }
135
136 fn to_be_bytes(&self) -> Self::Representation {
137 Self::to_be_bytes(*self)
138 }
139 })*
140 }
141}
142
143impl_representable!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, f32, f64);