Coverage Report

Created: 2025-05-07 06:59

/rust/registry/src/index.crates.io-6f17d22bba15001f/num-traits-0.2.19/src/ops/bytes.rs
Line
Count
Source (jump to first uncovered line)
1
use core::borrow::{Borrow, BorrowMut};
2
use core::cmp::{Eq, Ord, PartialEq, PartialOrd};
3
use core::fmt::Debug;
4
use core::hash::Hash;
5
6
pub trait NumBytes:
7
    Debug
8
    + AsRef<[u8]>
9
    + AsMut<[u8]>
10
    + PartialEq
11
    + Eq
12
    + PartialOrd
13
    + Ord
14
    + Hash
15
    + Borrow<[u8]>
16
    + BorrowMut<[u8]>
17
{
18
}
19
20
impl<T> NumBytes for T where
21
    T: Debug
22
        + AsRef<[u8]>
23
        + AsMut<[u8]>
24
        + PartialEq
25
        + Eq
26
        + PartialOrd
27
        + Ord
28
        + Hash
29
        + Borrow<[u8]>
30
        + BorrowMut<[u8]>
31
        + ?Sized
32
{
33
}
34
35
pub trait ToBytes {
36
    type Bytes: NumBytes;
37
38
    /// Return the memory representation of this number as a byte array in big-endian byte order.
39
    ///
40
    /// # Examples
41
    ///
42
    /// ```
43
    /// use num_traits::ToBytes;
44
    ///
45
    /// let bytes = ToBytes::to_be_bytes(&0x12345678u32);
46
    /// assert_eq!(bytes, [0x12, 0x34, 0x56, 0x78]);
47
    /// ```
48
    fn to_be_bytes(&self) -> Self::Bytes;
49
50
    /// Return the memory representation of this number as a byte array in little-endian byte order.
51
    ///
52
    /// # Examples
53
    ///
54
    /// ```
55
    /// use num_traits::ToBytes;
56
    ///
57
    /// let bytes = ToBytes::to_le_bytes(&0x12345678u32);
58
    /// assert_eq!(bytes, [0x78, 0x56, 0x34, 0x12]);
59
    /// ```
60
    fn to_le_bytes(&self) -> Self::Bytes;
61
62
    /// Return the memory representation of this number as a byte array in native byte order.
63
    ///
64
    /// As the target platform's native endianness is used,
65
    /// portable code should use [`to_be_bytes`] or [`to_le_bytes`], as appropriate, instead.
66
    ///
67
    /// [`to_be_bytes`]: #method.to_be_bytes
68
    /// [`to_le_bytes`]: #method.to_le_bytes
69
    ///
70
    /// # Examples
71
    ///
72
    /// ```
73
    /// use num_traits::ToBytes;
74
    ///
75
    /// #[cfg(target_endian = "big")]
76
    /// let expected = [0x12, 0x34, 0x56, 0x78];
77
    ///
78
    /// #[cfg(target_endian = "little")]
79
    /// let expected = [0x78, 0x56, 0x34, 0x12];
80
    ///
81
    /// let bytes = ToBytes::to_ne_bytes(&0x12345678u32);
82
    /// assert_eq!(bytes, expected)
83
    /// ```
84
0
    fn to_ne_bytes(&self) -> Self::Bytes {
85
0
        #[cfg(target_endian = "big")]
86
0
        let bytes = self.to_be_bytes();
87
0
        #[cfg(target_endian = "little")]
88
0
        let bytes = self.to_le_bytes();
89
0
        bytes
90
0
    }
91
}
92
93
pub trait FromBytes: Sized {
94
    type Bytes: NumBytes + ?Sized;
95
96
    /// Create a number from its representation as a byte array in big endian.
97
    ///
98
    /// # Examples
99
    ///
100
    /// ```
101
    /// use num_traits::FromBytes;
102
    ///
103
    /// let value: u32 = FromBytes::from_be_bytes(&[0x12, 0x34, 0x56, 0x78]);
104
    /// assert_eq!(value, 0x12345678);
105
    /// ```
106
    fn from_be_bytes(bytes: &Self::Bytes) -> Self;
107
108
    /// Create a number from its representation as a byte array in little endian.
109
    ///
110
    /// # Examples
111
    ///
112
    /// ```
113
    /// use num_traits::FromBytes;
114
    ///
115
    /// let value: u32 = FromBytes::from_le_bytes(&[0x78, 0x56, 0x34, 0x12]);
116
    /// assert_eq!(value, 0x12345678);
117
    /// ```
118
    fn from_le_bytes(bytes: &Self::Bytes) -> Self;
119
120
    /// Create a number from its memory representation as a byte array in native endianness.
121
    ///
122
    /// As the target platform's native endianness is used,
123
    /// portable code likely wants to use [`from_be_bytes`] or [`from_le_bytes`], as appropriate instead.
124
    ///
125
    /// [`from_be_bytes`]: #method.from_be_bytes
126
    /// [`from_le_bytes`]: #method.from_le_bytes
127
    ///
128
    /// # Examples
129
    ///
130
    /// ```
131
    /// use num_traits::FromBytes;
132
    ///
133
    /// #[cfg(target_endian = "big")]
134
    /// let bytes = [0x12, 0x34, 0x56, 0x78];
135
    ///
136
    /// #[cfg(target_endian = "little")]
137
    /// let bytes = [0x78, 0x56, 0x34, 0x12];
138
    ///
139
    /// let value: u32 = FromBytes::from_ne_bytes(&bytes);
140
    /// assert_eq!(value, 0x12345678)
141
    /// ```
142
0
    fn from_ne_bytes(bytes: &Self::Bytes) -> Self {
143
0
        #[cfg(target_endian = "big")]
144
0
        let this = Self::from_be_bytes(bytes);
145
0
        #[cfg(target_endian = "little")]
146
0
        let this = Self::from_le_bytes(bytes);
147
0
        this
148
0
    }
149
}
150
151
macro_rules! float_to_from_bytes_impl {
152
    ($T:ty, $L:expr) => {
153
        impl ToBytes for $T {
154
            type Bytes = [u8; $L];
155
156
            #[inline]
157
0
            fn to_be_bytes(&self) -> Self::Bytes {
158
0
                <$T>::to_be_bytes(*self)
159
0
            }
Unexecuted instantiation: <f32 as num_traits::ops::bytes::ToBytes>::to_be_bytes
Unexecuted instantiation: <f64 as num_traits::ops::bytes::ToBytes>::to_be_bytes
160
161
            #[inline]
162
0
            fn to_le_bytes(&self) -> Self::Bytes {
163
0
                <$T>::to_le_bytes(*self)
164
0
            }
Unexecuted instantiation: <f32 as num_traits::ops::bytes::ToBytes>::to_le_bytes
Unexecuted instantiation: <f64 as num_traits::ops::bytes::ToBytes>::to_le_bytes
165
166
            #[inline]
167
0
            fn to_ne_bytes(&self) -> Self::Bytes {
168
0
                <$T>::to_ne_bytes(*self)
169
0
            }
Unexecuted instantiation: <f32 as num_traits::ops::bytes::ToBytes>::to_ne_bytes
Unexecuted instantiation: <f64 as num_traits::ops::bytes::ToBytes>::to_ne_bytes
170
        }
171
172
        impl FromBytes for $T {
173
            type Bytes = [u8; $L];
174
175
            #[inline]
176
0
            fn from_be_bytes(bytes: &Self::Bytes) -> Self {
177
0
                <$T>::from_be_bytes(*bytes)
178
0
            }
Unexecuted instantiation: <f32 as num_traits::ops::bytes::FromBytes>::from_be_bytes
Unexecuted instantiation: <f64 as num_traits::ops::bytes::FromBytes>::from_be_bytes
179
180
            #[inline]
181
0
            fn from_le_bytes(bytes: &Self::Bytes) -> Self {
182
0
                <$T>::from_le_bytes(*bytes)
183
0
            }
Unexecuted instantiation: <f32 as num_traits::ops::bytes::FromBytes>::from_le_bytes
Unexecuted instantiation: <f64 as num_traits::ops::bytes::FromBytes>::from_le_bytes
184
185
            #[inline]
186
0
            fn from_ne_bytes(bytes: &Self::Bytes) -> Self {
187
0
                <$T>::from_ne_bytes(*bytes)
188
0
            }
Unexecuted instantiation: <f32 as num_traits::ops::bytes::FromBytes>::from_ne_bytes
Unexecuted instantiation: <f64 as num_traits::ops::bytes::FromBytes>::from_ne_bytes
189
        }
190
    };
191
}
192
193
macro_rules! int_to_from_bytes_impl {
194
    ($T:ty, $L:expr) => {
195
        impl ToBytes for $T {
196
            type Bytes = [u8; $L];
197
198
            #[inline]
199
0
            fn to_be_bytes(&self) -> Self::Bytes {
200
0
                <$T>::to_be_bytes(*self)
201
0
            }
Unexecuted instantiation: <u8 as num_traits::ops::bytes::ToBytes>::to_be_bytes
Unexecuted instantiation: <u16 as num_traits::ops::bytes::ToBytes>::to_be_bytes
Unexecuted instantiation: <u32 as num_traits::ops::bytes::ToBytes>::to_be_bytes
Unexecuted instantiation: <u64 as num_traits::ops::bytes::ToBytes>::to_be_bytes
Unexecuted instantiation: <u128 as num_traits::ops::bytes::ToBytes>::to_be_bytes
Unexecuted instantiation: <usize as num_traits::ops::bytes::ToBytes>::to_be_bytes
Unexecuted instantiation: <i8 as num_traits::ops::bytes::ToBytes>::to_be_bytes
Unexecuted instantiation: <i16 as num_traits::ops::bytes::ToBytes>::to_be_bytes
Unexecuted instantiation: <i32 as num_traits::ops::bytes::ToBytes>::to_be_bytes
Unexecuted instantiation: <i64 as num_traits::ops::bytes::ToBytes>::to_be_bytes
Unexecuted instantiation: <i128 as num_traits::ops::bytes::ToBytes>::to_be_bytes
Unexecuted instantiation: <isize as num_traits::ops::bytes::ToBytes>::to_be_bytes
202
203
            #[inline]
204
0
            fn to_le_bytes(&self) -> Self::Bytes {
205
0
                <$T>::to_le_bytes(*self)
206
0
            }
Unexecuted instantiation: <u8 as num_traits::ops::bytes::ToBytes>::to_le_bytes
Unexecuted instantiation: <u16 as num_traits::ops::bytes::ToBytes>::to_le_bytes
Unexecuted instantiation: <u32 as num_traits::ops::bytes::ToBytes>::to_le_bytes
Unexecuted instantiation: <u64 as num_traits::ops::bytes::ToBytes>::to_le_bytes
Unexecuted instantiation: <u128 as num_traits::ops::bytes::ToBytes>::to_le_bytes
Unexecuted instantiation: <usize as num_traits::ops::bytes::ToBytes>::to_le_bytes
Unexecuted instantiation: <i8 as num_traits::ops::bytes::ToBytes>::to_le_bytes
Unexecuted instantiation: <i16 as num_traits::ops::bytes::ToBytes>::to_le_bytes
Unexecuted instantiation: <i32 as num_traits::ops::bytes::ToBytes>::to_le_bytes
Unexecuted instantiation: <i64 as num_traits::ops::bytes::ToBytes>::to_le_bytes
Unexecuted instantiation: <i128 as num_traits::ops::bytes::ToBytes>::to_le_bytes
Unexecuted instantiation: <isize as num_traits::ops::bytes::ToBytes>::to_le_bytes
207
208
            #[inline]
209
0
            fn to_ne_bytes(&self) -> Self::Bytes {
210
0
                <$T>::to_ne_bytes(*self)
211
0
            }
Unexecuted instantiation: <u8 as num_traits::ops::bytes::ToBytes>::to_ne_bytes
Unexecuted instantiation: <u16 as num_traits::ops::bytes::ToBytes>::to_ne_bytes
Unexecuted instantiation: <u32 as num_traits::ops::bytes::ToBytes>::to_ne_bytes
Unexecuted instantiation: <u64 as num_traits::ops::bytes::ToBytes>::to_ne_bytes
Unexecuted instantiation: <u128 as num_traits::ops::bytes::ToBytes>::to_ne_bytes
Unexecuted instantiation: <usize as num_traits::ops::bytes::ToBytes>::to_ne_bytes
Unexecuted instantiation: <i8 as num_traits::ops::bytes::ToBytes>::to_ne_bytes
Unexecuted instantiation: <i16 as num_traits::ops::bytes::ToBytes>::to_ne_bytes
Unexecuted instantiation: <i32 as num_traits::ops::bytes::ToBytes>::to_ne_bytes
Unexecuted instantiation: <i64 as num_traits::ops::bytes::ToBytes>::to_ne_bytes
Unexecuted instantiation: <i128 as num_traits::ops::bytes::ToBytes>::to_ne_bytes
Unexecuted instantiation: <isize as num_traits::ops::bytes::ToBytes>::to_ne_bytes
212
        }
213
214
        impl FromBytes for $T {
215
            type Bytes = [u8; $L];
216
217
            #[inline]
218
0
            fn from_be_bytes(bytes: &Self::Bytes) -> Self {
219
0
                <$T>::from_be_bytes(*bytes)
220
0
            }
Unexecuted instantiation: <u8 as num_traits::ops::bytes::FromBytes>::from_be_bytes
Unexecuted instantiation: <u16 as num_traits::ops::bytes::FromBytes>::from_be_bytes
Unexecuted instantiation: <u32 as num_traits::ops::bytes::FromBytes>::from_be_bytes
Unexecuted instantiation: <u64 as num_traits::ops::bytes::FromBytes>::from_be_bytes
Unexecuted instantiation: <u128 as num_traits::ops::bytes::FromBytes>::from_be_bytes
Unexecuted instantiation: <usize as num_traits::ops::bytes::FromBytes>::from_be_bytes
Unexecuted instantiation: <i8 as num_traits::ops::bytes::FromBytes>::from_be_bytes
Unexecuted instantiation: <i16 as num_traits::ops::bytes::FromBytes>::from_be_bytes
Unexecuted instantiation: <i32 as num_traits::ops::bytes::FromBytes>::from_be_bytes
Unexecuted instantiation: <i64 as num_traits::ops::bytes::FromBytes>::from_be_bytes
Unexecuted instantiation: <i128 as num_traits::ops::bytes::FromBytes>::from_be_bytes
Unexecuted instantiation: <isize as num_traits::ops::bytes::FromBytes>::from_be_bytes
221
222
            #[inline]
223
0
            fn from_le_bytes(bytes: &Self::Bytes) -> Self {
224
0
                <$T>::from_le_bytes(*bytes)
225
0
            }
Unexecuted instantiation: <u8 as num_traits::ops::bytes::FromBytes>::from_le_bytes
Unexecuted instantiation: <u16 as num_traits::ops::bytes::FromBytes>::from_le_bytes
Unexecuted instantiation: <u32 as num_traits::ops::bytes::FromBytes>::from_le_bytes
Unexecuted instantiation: <u64 as num_traits::ops::bytes::FromBytes>::from_le_bytes
Unexecuted instantiation: <u128 as num_traits::ops::bytes::FromBytes>::from_le_bytes
Unexecuted instantiation: <usize as num_traits::ops::bytes::FromBytes>::from_le_bytes
Unexecuted instantiation: <i8 as num_traits::ops::bytes::FromBytes>::from_le_bytes
Unexecuted instantiation: <i16 as num_traits::ops::bytes::FromBytes>::from_le_bytes
Unexecuted instantiation: <i32 as num_traits::ops::bytes::FromBytes>::from_le_bytes
Unexecuted instantiation: <i64 as num_traits::ops::bytes::FromBytes>::from_le_bytes
Unexecuted instantiation: <i128 as num_traits::ops::bytes::FromBytes>::from_le_bytes
Unexecuted instantiation: <isize as num_traits::ops::bytes::FromBytes>::from_le_bytes
226
227
            #[inline]
228
0
            fn from_ne_bytes(bytes: &Self::Bytes) -> Self {
229
0
                <$T>::from_ne_bytes(*bytes)
230
0
            }
Unexecuted instantiation: <u8 as num_traits::ops::bytes::FromBytes>::from_ne_bytes
Unexecuted instantiation: <u16 as num_traits::ops::bytes::FromBytes>::from_ne_bytes
Unexecuted instantiation: <u32 as num_traits::ops::bytes::FromBytes>::from_ne_bytes
Unexecuted instantiation: <u64 as num_traits::ops::bytes::FromBytes>::from_ne_bytes
Unexecuted instantiation: <u128 as num_traits::ops::bytes::FromBytes>::from_ne_bytes
Unexecuted instantiation: <usize as num_traits::ops::bytes::FromBytes>::from_ne_bytes
Unexecuted instantiation: <i8 as num_traits::ops::bytes::FromBytes>::from_ne_bytes
Unexecuted instantiation: <i16 as num_traits::ops::bytes::FromBytes>::from_ne_bytes
Unexecuted instantiation: <i32 as num_traits::ops::bytes::FromBytes>::from_ne_bytes
Unexecuted instantiation: <i64 as num_traits::ops::bytes::FromBytes>::from_ne_bytes
Unexecuted instantiation: <i128 as num_traits::ops::bytes::FromBytes>::from_ne_bytes
Unexecuted instantiation: <isize as num_traits::ops::bytes::FromBytes>::from_ne_bytes
231
        }
232
    };
233
}
234
235
int_to_from_bytes_impl!(u8, 1);
236
int_to_from_bytes_impl!(u16, 2);
237
int_to_from_bytes_impl!(u32, 4);
238
int_to_from_bytes_impl!(u64, 8);
239
int_to_from_bytes_impl!(u128, 16);
240
#[cfg(target_pointer_width = "64")]
241
int_to_from_bytes_impl!(usize, 8);
242
#[cfg(target_pointer_width = "32")]
243
int_to_from_bytes_impl!(usize, 4);
244
245
int_to_from_bytes_impl!(i8, 1);
246
int_to_from_bytes_impl!(i16, 2);
247
int_to_from_bytes_impl!(i32, 4);
248
int_to_from_bytes_impl!(i64, 8);
249
int_to_from_bytes_impl!(i128, 16);
250
#[cfg(target_pointer_width = "64")]
251
int_to_from_bytes_impl!(isize, 8);
252
#[cfg(target_pointer_width = "32")]
253
int_to_from_bytes_impl!(isize, 4);
254
255
float_to_from_bytes_impl!(f32, 4);
256
float_to_from_bytes_impl!(f64, 8);
257
258
#[cfg(test)]
259
mod tests {
260
    use super::*;
261
262
    macro_rules! check_to_from_bytes {
263
        ($( $ty:ty )+) => {$({
264
            let n = 1;
265
            let be = <$ty as ToBytes>::to_be_bytes(&n);
266
            let le = <$ty as ToBytes>::to_le_bytes(&n);
267
            let ne = <$ty as ToBytes>::to_ne_bytes(&n);
268
269
            assert_eq!(*be.last().unwrap(), 1);
270
            assert_eq!(*le.first().unwrap(), 1);
271
            if cfg!(target_endian = "big") {
272
                assert_eq!(*ne.last().unwrap(), 1);
273
            } else {
274
                assert_eq!(*ne.first().unwrap(), 1);
275
            }
276
277
            assert_eq!(<$ty as FromBytes>::from_be_bytes(&be), n);
278
            assert_eq!(<$ty as FromBytes>::from_le_bytes(&le), n);
279
            if cfg!(target_endian = "big") {
280
                assert_eq!(<$ty as FromBytes>::from_ne_bytes(&be), n);
281
            } else {
282
                assert_eq!(<$ty as FromBytes>::from_ne_bytes(&le), n);
283
            }
284
        })+}
285
    }
286
287
    #[test]
288
    fn convert_between_int_and_bytes() {
289
        check_to_from_bytes!(u8 u16 u32 u64 u128 usize);
290
        check_to_from_bytes!(i8 i16 i32 i64 i128 isize);
291
    }
292
293
    #[test]
294
    fn convert_between_float_and_bytes() {
295
        macro_rules! check_to_from_bytes {
296
            ($( $ty:ty )+) => {$(
297
                let n: $ty = 3.14;
298
299
                let be = <$ty as ToBytes>::to_be_bytes(&n);
300
                let le = <$ty as ToBytes>::to_le_bytes(&n);
301
                let ne = <$ty as ToBytes>::to_ne_bytes(&n);
302
303
                assert_eq!(<$ty as FromBytes>::from_be_bytes(&be), n);
304
                assert_eq!(<$ty as FromBytes>::from_le_bytes(&le), n);
305
                if cfg!(target_endian = "big") {
306
                    assert_eq!(ne, be);
307
                    assert_eq!(<$ty as FromBytes>::from_ne_bytes(&be), n);
308
                } else {
309
                    assert_eq!(ne, le);
310
                    assert_eq!(<$ty as FromBytes>::from_ne_bytes(&le), n);
311
                }
312
            )+}
313
        }
314
315
        check_to_from_bytes!(f32 f64);
316
    }
317
}