Coverage Report

Created: 2024-10-16 07:58

/rust/registry/src/index.crates.io-6f17d22bba15001f/object-0.36.1/src/endian.rs
Line
Count
Source (jump to first uncovered line)
1
//! Types for compile-time and run-time endianness.
2
3
use crate::pod::Pod;
4
use core::fmt::{self, Debug};
5
use core::marker::PhantomData;
6
7
/// A trait for using an endianness specification.
8
///
9
/// Provides methods for converting between the specified endianness and
10
/// the native endianness of the target machine.
11
///
12
/// This trait does not require that the endianness is known at compile time.
13
pub trait Endian: Debug + Default + Clone + Copy + PartialEq + Eq + 'static {
14
    /// Construct a specification for the endianness of some values.
15
    ///
16
    /// Returns `None` if the type does not support specifying the given endianness.
17
    fn from_big_endian(big_endian: bool) -> Option<Self>;
18
19
    /// Construct a specification for the endianness of some values.
20
    ///
21
    /// Returns `None` if the type does not support specifying the given endianness.
22
0
    fn from_little_endian(little_endian: bool) -> Option<Self> {
23
0
        Self::from_big_endian(!little_endian)
24
0
    }
Unexecuted instantiation: <object::endian::Endianness as object::endian::Endian>::from_little_endian
Unexecuted instantiation: <object::endian::LittleEndian as object::endian::Endian>::from_little_endian
Unexecuted instantiation: <object::endian::BigEndian as object::endian::Endian>::from_little_endian
25
26
    /// Return true for big endian byte order.
27
    fn is_big_endian(self) -> bool;
28
29
    /// Return true for little endian byte order.
30
    #[inline]
31
0
    fn is_little_endian(self) -> bool {
32
0
        !self.is_big_endian()
33
0
    }
Unexecuted instantiation: <object::endian::Endianness as object::endian::Endian>::is_little_endian
Unexecuted instantiation: <object::endian::LittleEndian as object::endian::Endian>::is_little_endian
Unexecuted instantiation: <object::endian::BigEndian as object::endian::Endian>::is_little_endian
34
35
    /// Converts an unsigned 16 bit integer to native endian.
36
    #[inline]
37
0
    fn read_u16(self, n: u16) -> u16 {
38
0
        if self.is_big_endian() {
39
0
            u16::from_be(n)
40
        } else {
41
0
            u16::from_le(n)
42
        }
43
0
    }
Unexecuted instantiation: <object::endian::Endianness as object::endian::Endian>::read_u16
Unexecuted instantiation: <object::endian::LittleEndian as object::endian::Endian>::read_u16
Unexecuted instantiation: <object::endian::BigEndian as object::endian::Endian>::read_u16
44
45
    /// Converts an unsigned 32 bit integer to native endian.
46
    #[inline]
47
0
    fn read_u32(self, n: u32) -> u32 {
48
0
        if self.is_big_endian() {
49
0
            u32::from_be(n)
50
        } else {
51
0
            u32::from_le(n)
52
        }
53
0
    }
Unexecuted instantiation: <object::endian::Endianness as object::endian::Endian>::read_u32
Unexecuted instantiation: <object::endian::LittleEndian as object::endian::Endian>::read_u32
Unexecuted instantiation: <object::endian::BigEndian as object::endian::Endian>::read_u32
54
55
    /// Converts an unsigned 64 bit integer to native endian.
56
    #[inline]
57
0
    fn read_u64(self, n: u64) -> u64 {
58
0
        if self.is_big_endian() {
59
0
            u64::from_be(n)
60
        } else {
61
0
            u64::from_le(n)
62
        }
63
0
    }
Unexecuted instantiation: <object::endian::Endianness as object::endian::Endian>::read_u64
Unexecuted instantiation: <object::endian::LittleEndian as object::endian::Endian>::read_u64
Unexecuted instantiation: <object::endian::BigEndian as object::endian::Endian>::read_u64
64
65
    /// Converts a signed 16 bit integer to native endian.
66
    #[inline]
67
0
    fn read_i16(self, n: i16) -> i16 {
68
0
        if self.is_big_endian() {
69
0
            i16::from_be(n)
70
        } else {
71
0
            i16::from_le(n)
72
        }
73
0
    }
Unexecuted instantiation: <object::endian::Endianness as object::endian::Endian>::read_i16
Unexecuted instantiation: <object::endian::LittleEndian as object::endian::Endian>::read_i16
Unexecuted instantiation: <object::endian::BigEndian as object::endian::Endian>::read_i16
74
75
    /// Converts a signed 32 bit integer to native endian.
76
    #[inline]
77
0
    fn read_i32(self, n: i32) -> i32 {
78
0
        if self.is_big_endian() {
79
0
            i32::from_be(n)
80
        } else {
81
0
            i32::from_le(n)
82
        }
83
0
    }
Unexecuted instantiation: <object::endian::Endianness as object::endian::Endian>::read_i32
Unexecuted instantiation: <object::endian::LittleEndian as object::endian::Endian>::read_i32
Unexecuted instantiation: <object::endian::BigEndian as object::endian::Endian>::read_i32
84
85
    /// Converts a signed 64 bit integer to native endian.
86
    #[inline]
87
0
    fn read_i64(self, n: i64) -> i64 {
88
0
        if self.is_big_endian() {
89
0
            i64::from_be(n)
90
        } else {
91
0
            i64::from_le(n)
92
        }
93
0
    }
Unexecuted instantiation: <object::endian::Endianness as object::endian::Endian>::read_i64
Unexecuted instantiation: <object::endian::LittleEndian as object::endian::Endian>::read_i64
Unexecuted instantiation: <object::endian::BigEndian as object::endian::Endian>::read_i64
94
95
    /// Converts an unaligned unsigned 16 bit integer to native endian.
96
    #[inline]
97
0
    fn read_u16_bytes(self, n: [u8; 2]) -> u16 {
98
0
        if self.is_big_endian() {
99
0
            u16::from_be_bytes(n)
100
        } else {
101
0
            u16::from_le_bytes(n)
102
        }
103
0
    }
Unexecuted instantiation: <object::endian::LittleEndian as object::endian::Endian>::read_u16_bytes
Unexecuted instantiation: <object::endian::Endianness as object::endian::Endian>::read_u16_bytes
Unexecuted instantiation: <object::endian::LittleEndian as object::endian::Endian>::read_u16_bytes
Unexecuted instantiation: <object::endian::BigEndian as object::endian::Endian>::read_u16_bytes
104
105
    /// Converts an unaligned unsigned 32 bit integer to native endian.
106
    #[inline]
107
0
    fn read_u32_bytes(self, n: [u8; 4]) -> u32 {
108
0
        if self.is_big_endian() {
109
0
            u32::from_be_bytes(n)
110
        } else {
111
0
            u32::from_le_bytes(n)
112
        }
113
0
    }
Unexecuted instantiation: <object::endian::LittleEndian as object::endian::Endian>::read_u32_bytes
Unexecuted instantiation: <object::endian::BigEndian as object::endian::Endian>::read_u32_bytes
Unexecuted instantiation: <object::endian::Endianness as object::endian::Endian>::read_u32_bytes
Unexecuted instantiation: <object::endian::LittleEndian as object::endian::Endian>::read_u32_bytes
Unexecuted instantiation: <object::endian::BigEndian as object::endian::Endian>::read_u32_bytes
114
115
    /// Converts an unaligned unsigned 64 bit integer to native endian.
116
    #[inline]
117
0
    fn read_u64_bytes(self, n: [u8; 8]) -> u64 {
118
0
        if self.is_big_endian() {
119
0
            u64::from_be_bytes(n)
120
        } else {
121
0
            u64::from_le_bytes(n)
122
        }
123
0
    }
Unexecuted instantiation: <object::endian::LittleEndian as object::endian::Endian>::read_u64_bytes
Unexecuted instantiation: <object::endian::Endianness as object::endian::Endian>::read_u64_bytes
Unexecuted instantiation: <object::endian::LittleEndian as object::endian::Endian>::read_u64_bytes
Unexecuted instantiation: <object::endian::BigEndian as object::endian::Endian>::read_u64_bytes
124
125
    /// Converts an unaligned signed 16 bit integer to native endian.
126
    #[inline]
127
0
    fn read_i16_bytes(self, n: [u8; 2]) -> i16 {
128
0
        if self.is_big_endian() {
129
0
            i16::from_be_bytes(n)
130
        } else {
131
0
            i16::from_le_bytes(n)
132
        }
133
0
    }
Unexecuted instantiation: <object::endian::Endianness as object::endian::Endian>::read_i16_bytes
Unexecuted instantiation: <object::endian::LittleEndian as object::endian::Endian>::read_i16_bytes
Unexecuted instantiation: <object::endian::BigEndian as object::endian::Endian>::read_i16_bytes
134
135
    /// Converts an unaligned signed 32 bit integer to native endian.
136
    #[inline]
137
0
    fn read_i32_bytes(self, n: [u8; 4]) -> i32 {
138
0
        if self.is_big_endian() {
139
0
            i32::from_be_bytes(n)
140
        } else {
141
0
            i32::from_le_bytes(n)
142
        }
143
0
    }
Unexecuted instantiation: <object::endian::Endianness as object::endian::Endian>::read_i32_bytes
Unexecuted instantiation: <object::endian::LittleEndian as object::endian::Endian>::read_i32_bytes
Unexecuted instantiation: <object::endian::BigEndian as object::endian::Endian>::read_i32_bytes
144
145
    /// Converts an unaligned signed 64 bit integer to native endian.
146
    #[inline]
147
0
    fn read_i64_bytes(self, n: [u8; 8]) -> i64 {
148
0
        if self.is_big_endian() {
149
0
            i64::from_be_bytes(n)
150
        } else {
151
0
            i64::from_le_bytes(n)
152
        }
153
0
    }
Unexecuted instantiation: <object::endian::Endianness as object::endian::Endian>::read_i64_bytes
Unexecuted instantiation: <object::endian::LittleEndian as object::endian::Endian>::read_i64_bytes
Unexecuted instantiation: <object::endian::BigEndian as object::endian::Endian>::read_i64_bytes
154
155
    /// Converts an unsigned 16 bit integer from native endian.
156
    #[inline]
157
0
    fn write_u16(self, n: u16) -> u16 {
158
0
        if self.is_big_endian() {
159
0
            u16::to_be(n)
160
        } else {
161
0
            u16::to_le(n)
162
        }
163
0
    }
Unexecuted instantiation: <object::endian::Endianness as object::endian::Endian>::write_u16
Unexecuted instantiation: <object::endian::LittleEndian as object::endian::Endian>::write_u16
Unexecuted instantiation: <object::endian::BigEndian as object::endian::Endian>::write_u16
164
165
    /// Converts an unsigned 32 bit integer from native endian.
166
    #[inline]
167
0
    fn write_u32(self, n: u32) -> u32 {
168
0
        if self.is_big_endian() {
169
0
            u32::to_be(n)
170
        } else {
171
0
            u32::to_le(n)
172
        }
173
0
    }
Unexecuted instantiation: <object::endian::Endianness as object::endian::Endian>::write_u32
Unexecuted instantiation: <object::endian::LittleEndian as object::endian::Endian>::write_u32
Unexecuted instantiation: <object::endian::BigEndian as object::endian::Endian>::write_u32
174
175
    /// Converts an unsigned 64 bit integer from native endian.
176
    #[inline]
177
0
    fn write_u64(self, n: u64) -> u64 {
178
0
        if self.is_big_endian() {
179
0
            u64::to_be(n)
180
        } else {
181
0
            u64::to_le(n)
182
        }
183
0
    }
Unexecuted instantiation: <object::endian::Endianness as object::endian::Endian>::write_u64
Unexecuted instantiation: <object::endian::LittleEndian as object::endian::Endian>::write_u64
Unexecuted instantiation: <object::endian::BigEndian as object::endian::Endian>::write_u64
184
185
    /// Converts a signed 16 bit integer from native endian.
186
    #[inline]
187
0
    fn write_i16(self, n: i16) -> i16 {
188
0
        if self.is_big_endian() {
189
0
            i16::to_be(n)
190
        } else {
191
0
            i16::to_le(n)
192
        }
193
0
    }
Unexecuted instantiation: <object::endian::Endianness as object::endian::Endian>::write_i16
Unexecuted instantiation: <object::endian::LittleEndian as object::endian::Endian>::write_i16
Unexecuted instantiation: <object::endian::BigEndian as object::endian::Endian>::write_i16
194
195
    /// Converts a signed 32 bit integer from native endian.
196
    #[inline]
197
0
    fn write_i32(self, n: i32) -> i32 {
198
0
        if self.is_big_endian() {
199
0
            i32::to_be(n)
200
        } else {
201
0
            i32::to_le(n)
202
        }
203
0
    }
Unexecuted instantiation: <object::endian::Endianness as object::endian::Endian>::write_i32
Unexecuted instantiation: <object::endian::LittleEndian as object::endian::Endian>::write_i32
Unexecuted instantiation: <object::endian::BigEndian as object::endian::Endian>::write_i32
204
205
    /// Converts a signed 64 bit integer from native endian.
206
    #[inline]
207
0
    fn write_i64(self, n: i64) -> i64 {
208
0
        if self.is_big_endian() {
209
0
            i64::to_be(n)
210
        } else {
211
0
            i64::to_le(n)
212
        }
213
0
    }
Unexecuted instantiation: <object::endian::Endianness as object::endian::Endian>::write_i64
Unexecuted instantiation: <object::endian::LittleEndian as object::endian::Endian>::write_i64
Unexecuted instantiation: <object::endian::BigEndian as object::endian::Endian>::write_i64
214
215
    /// Converts an unaligned unsigned 16 bit integer from native endian.
216
    #[inline]
217
0
    fn write_u16_bytes(self, n: u16) -> [u8; 2] {
218
0
        if self.is_big_endian() {
219
0
            u16::to_be_bytes(n)
220
        } else {
221
0
            u16::to_le_bytes(n)
222
        }
223
0
    }
Unexecuted instantiation: <object::endian::Endianness as object::endian::Endian>::write_u16_bytes
Unexecuted instantiation: <object::endian::LittleEndian as object::endian::Endian>::write_u16_bytes
Unexecuted instantiation: <object::endian::BigEndian as object::endian::Endian>::write_u16_bytes
224
225
    /// Converts an unaligned unsigned 32 bit integer from native endian.
226
    #[inline]
227
0
    fn write_u32_bytes(self, n: u32) -> [u8; 4] {
228
0
        if self.is_big_endian() {
229
0
            u32::to_be_bytes(n)
230
        } else {
231
0
            u32::to_le_bytes(n)
232
        }
233
0
    }
Unexecuted instantiation: <object::endian::Endianness as object::endian::Endian>::write_u32_bytes
Unexecuted instantiation: <object::endian::LittleEndian as object::endian::Endian>::write_u32_bytes
Unexecuted instantiation: <object::endian::BigEndian as object::endian::Endian>::write_u32_bytes
234
235
    /// Converts an unaligned unsigned 64 bit integer from native endian.
236
    #[inline]
237
0
    fn write_u64_bytes(self, n: u64) -> [u8; 8] {
238
0
        if self.is_big_endian() {
239
0
            u64::to_be_bytes(n)
240
        } else {
241
0
            u64::to_le_bytes(n)
242
        }
243
0
    }
Unexecuted instantiation: <object::endian::Endianness as object::endian::Endian>::write_u64_bytes
Unexecuted instantiation: <object::endian::LittleEndian as object::endian::Endian>::write_u64_bytes
Unexecuted instantiation: <object::endian::BigEndian as object::endian::Endian>::write_u64_bytes
244
245
    /// Converts an unaligned signed 16 bit integer from native endian.
246
    #[inline]
247
0
    fn write_i16_bytes(self, n: i16) -> [u8; 2] {
248
0
        if self.is_big_endian() {
249
0
            i16::to_be_bytes(n)
250
        } else {
251
0
            i16::to_le_bytes(n)
252
        }
253
0
    }
Unexecuted instantiation: <object::endian::Endianness as object::endian::Endian>::write_i16_bytes
Unexecuted instantiation: <object::endian::LittleEndian as object::endian::Endian>::write_i16_bytes
Unexecuted instantiation: <object::endian::BigEndian as object::endian::Endian>::write_i16_bytes
254
255
    /// Converts an unaligned signed 32 bit integer from native endian.
256
    #[inline]
257
0
    fn write_i32_bytes(self, n: i32) -> [u8; 4] {
258
0
        if self.is_big_endian() {
259
0
            i32::to_be_bytes(n)
260
        } else {
261
0
            i32::to_le_bytes(n)
262
        }
263
0
    }
Unexecuted instantiation: <object::endian::Endianness as object::endian::Endian>::write_i32_bytes
Unexecuted instantiation: <object::endian::LittleEndian as object::endian::Endian>::write_i32_bytes
Unexecuted instantiation: <object::endian::BigEndian as object::endian::Endian>::write_i32_bytes
264
265
    /// Converts an unaligned signed 64 bit integer from native endian.
266
    #[inline]
267
0
    fn write_i64_bytes(self, n: i64) -> [u8; 8] {
268
0
        if self.is_big_endian() {
269
0
            i64::to_be_bytes(n)
270
        } else {
271
0
            i64::to_le_bytes(n)
272
        }
273
0
    }
Unexecuted instantiation: <object::endian::Endianness as object::endian::Endian>::write_i64_bytes
Unexecuted instantiation: <object::endian::LittleEndian as object::endian::Endian>::write_i64_bytes
Unexecuted instantiation: <object::endian::BigEndian as object::endian::Endian>::write_i64_bytes
274
}
275
276
/// An endianness that is selectable at run-time.
277
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
278
pub enum Endianness {
279
    /// Little endian byte order.
280
    Little,
281
    /// Big endian byte order.
282
    Big,
283
}
284
285
impl Default for Endianness {
286
    #[cfg(target_endian = "little")]
287
    #[inline]
288
0
    fn default() -> Endianness {
289
0
        Endianness::Little
290
0
    }
291
292
    #[cfg(target_endian = "big")]
293
    #[inline]
294
    fn default() -> Endianness {
295
        Endianness::Big
296
    }
297
}
298
299
impl Endian for Endianness {
300
    #[inline]
301
0
    fn from_big_endian(big_endian: bool) -> Option<Self> {
302
0
        Some(if big_endian {
303
0
            Endianness::Big
304
        } else {
305
0
            Endianness::Little
306
        })
307
0
    }
308
309
    #[inline]
310
0
    fn is_big_endian(self) -> bool {
311
0
        self != Endianness::Little
312
0
    }
313
}
314
315
/// Compile-time little endian byte order.
316
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
317
pub struct LittleEndian;
318
319
impl Default for LittleEndian {
320
    #[inline]
321
0
    fn default() -> LittleEndian {
322
0
        LittleEndian
323
0
    }
324
}
325
326
impl Endian for LittleEndian {
327
    #[inline]
328
0
    fn from_big_endian(big_endian: bool) -> Option<Self> {
329
0
        if big_endian {
330
0
            None
331
        } else {
332
0
            Some(LittleEndian)
333
        }
334
0
    }
Unexecuted instantiation: <object::endian::LittleEndian as object::endian::Endian>::from_big_endian
Unexecuted instantiation: <object::endian::LittleEndian as object::endian::Endian>::from_big_endian
335
336
    #[inline]
337
0
    fn is_big_endian(self) -> bool {
338
0
        false
339
0
    }
Unexecuted instantiation: <object::endian::LittleEndian as object::endian::Endian>::is_big_endian
Unexecuted instantiation: <object::endian::LittleEndian as object::endian::Endian>::is_big_endian
340
}
341
342
/// Compile-time big endian byte order.
343
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
344
pub struct BigEndian;
345
346
impl Default for BigEndian {
347
    #[inline]
348
0
    fn default() -> BigEndian {
349
0
        BigEndian
350
0
    }
351
}
352
353
impl Endian for BigEndian {
354
    #[inline]
355
0
    fn from_big_endian(big_endian: bool) -> Option<Self> {
356
0
        if big_endian {
357
0
            Some(BigEndian)
358
        } else {
359
0
            None
360
        }
361
0
    }
362
363
    #[inline]
364
0
    fn is_big_endian(self) -> bool {
365
0
        true
366
0
    }
Unexecuted instantiation: <object::endian::BigEndian as object::endian::Endian>::is_big_endian
Unexecuted instantiation: <object::endian::BigEndian as object::endian::Endian>::is_big_endian
367
}
368
369
/// The native endianness for the target platform.
370
#[cfg(target_endian = "little")]
371
pub type NativeEndian = LittleEndian;
372
373
#[cfg(target_endian = "little")]
374
#[allow(non_upper_case_globals)]
375
#[doc(hidden)]
376
pub const NativeEndian: LittleEndian = LittleEndian;
377
378
/// The native endianness for the target platform.
379
#[cfg(target_endian = "big")]
380
pub type NativeEndian = BigEndian;
381
382
#[cfg(target_endian = "big")]
383
#[allow(non_upper_case_globals)]
384
#[doc(hidden)]
385
pub const NativeEndian: BigEndian = BigEndian;
386
387
macro_rules! unsafe_impl_endian_pod {
388
    ($($struct_name:ident),+ $(,)?) => {
389
        $(
390
            unsafe impl<E: Endian> Pod for $struct_name<E> { }
391
        )+
392
    }
393
}
394
395
#[cfg(not(feature = "unaligned"))]
396
mod aligned {
397
    use super::{fmt, Endian, PhantomData, Pod};
398
399
    /// A `u16` value with an externally specified endianness of type `E`.
400
    #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
401
    #[repr(transparent)]
402
    pub struct U16<E: Endian>(u16, PhantomData<E>);
403
404
    impl<E: Endian> U16<E> {
405
        /// Construct a new value given bytes that already have the required endianness.
406
        pub fn from_bytes(n: [u8; 2]) -> Self {
407
            Self(u16::from_ne_bytes(n), PhantomData)
408
        }
409
410
        /// Construct a new value given a native endian value.
411
        pub fn new(e: E, n: u16) -> Self {
412
            Self(e.write_u16(n), PhantomData)
413
        }
414
415
        /// Return the value as a native endian value.
416
        pub fn get(self, e: E) -> u16 {
417
            e.read_u16(self.0)
418
        }
419
420
        /// Set the value given a native endian value.
421
        pub fn set(&mut self, e: E, n: u16) {
422
            self.0 = e.write_u16(n);
423
        }
424
    }
425
426
    /// A `u32` value with an externally specified endianness of type `E`.
427
    #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
428
    #[repr(transparent)]
429
    pub struct U32<E: Endian>(u32, PhantomData<E>);
430
431
    impl<E: Endian> U32<E> {
432
        /// Construct a new value given bytes that already have the required endianness.
433
        pub fn from_bytes(n: [u8; 4]) -> Self {
434
            Self(u32::from_ne_bytes(n), PhantomData)
435
        }
436
437
        /// Construct a new value given a native endian value.
438
        pub fn new(e: E, n: u32) -> Self {
439
            Self(e.write_u32(n), PhantomData)
440
        }
441
        /// Return the value as a native endian value.
442
        pub fn get(self, e: E) -> u32 {
443
            e.read_u32(self.0)
444
        }
445
        /// Set the value given a native endian value.
446
        pub fn set(&mut self, e: E, n: u32) {
447
            self.0 = e.write_u32(n);
448
        }
449
    }
450
451
    /// A `u64` value with an externally specified endianness of type `E`.
452
    #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
453
    #[repr(transparent)]
454
    pub struct U64<E: Endian>(u64, PhantomData<E>);
455
456
    impl<E: Endian> U64<E> {
457
        /// Construct a new value given bytes that already have the required endianness.
458
        pub fn from_bytes(n: [u8; 8]) -> Self {
459
            Self(u64::from_ne_bytes(n), PhantomData)
460
        }
461
462
        /// Construct a new value given a native endian value.
463
        pub fn new(e: E, n: u64) -> Self {
464
            Self(e.write_u64(n), PhantomData)
465
        }
466
        /// Return the value as a native endian value.
467
        pub fn get(self, e: E) -> u64 {
468
            e.read_u64(self.0)
469
        }
470
        /// Set the value given a native endian value.
471
        pub fn set(&mut self, e: E, n: u64) {
472
            self.0 = e.write_u64(n);
473
        }
474
    }
475
476
    /// An `i16` value with an externally specified endianness of type `E`.
477
    #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
478
    #[repr(transparent)]
479
    pub struct I16<E: Endian>(i16, PhantomData<E>);
480
481
    impl<E: Endian> I16<E> {
482
        /// Construct a new value given bytes that already have the required endianness.
483
        pub fn from_bytes(n: [u8; 2]) -> Self {
484
            Self(i16::from_ne_bytes(n), PhantomData)
485
        }
486
487
        /// Construct a new value given a native endian value.
488
        pub fn new(e: E, n: i16) -> Self {
489
            Self(e.write_i16(n), PhantomData)
490
        }
491
        /// Return the value as a native endian value.
492
        pub fn get(self, e: E) -> i16 {
493
            e.read_i16(self.0)
494
        }
495
        /// Set the value given a native endian value.
496
        pub fn set(&mut self, e: E, n: i16) {
497
            self.0 = e.write_i16(n);
498
        }
499
    }
500
501
    /// An `i32` value with an externally specified endianness of type `E`.
502
    #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
503
    #[repr(transparent)]
504
    pub struct I32<E: Endian>(i32, PhantomData<E>);
505
506
    impl<E: Endian> I32<E> {
507
        /// Construct a new value given bytes that already have the required endianness.
508
        pub fn from_bytes(n: [u8; 4]) -> Self {
509
            Self(i32::from_ne_bytes(n), PhantomData)
510
        }
511
512
        /// Construct a new value given a native endian value.
513
        pub fn new(e: E, n: i32) -> Self {
514
            Self(e.write_i32(n), PhantomData)
515
        }
516
        /// Return the value as a native endian value.
517
        pub fn get(self, e: E) -> i32 {
518
            e.read_i32(self.0)
519
        }
520
        /// Set the value given a native endian value.
521
        pub fn set(&mut self, e: E, n: i32) {
522
            self.0 = e.write_i32(n);
523
        }
524
    }
525
526
    /// An `i64` value with an externally specified endianness of type `E`.
527
    #[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
528
    #[repr(transparent)]
529
    pub struct I64<E: Endian>(i64, PhantomData<E>);
530
531
    impl<E: Endian> I64<E> {
532
        /// Construct a new value given bytes that already have the required endianness.
533
        pub fn from_bytes(n: [u8; 8]) -> Self {
534
            Self(i64::from_ne_bytes(n), PhantomData)
535
        }
536
537
        /// Construct a new value given a native endian value.
538
        pub fn new(e: E, n: i64) -> Self {
539
            Self(e.write_i64(n), PhantomData)
540
        }
541
        /// Return the value as a native endian value.
542
        pub fn get(self, e: E) -> i64 {
543
            e.read_i64(self.0)
544
        }
545
        /// Set the value given a native endian value.
546
        pub fn set(&mut self, e: E, n: i64) {
547
            self.0 = e.write_i64(n);
548
        }
549
    }
550
551
    impl<E: Endian> fmt::Debug for U16<E> {
552
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
553
            write!(f, "U16({:x})", self.0)
554
        }
555
    }
556
557
    impl<E: Endian> fmt::Debug for U32<E> {
558
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
559
            write!(f, "U32({:x})", self.0)
560
        }
561
    }
562
563
    impl<E: Endian> fmt::Debug for U64<E> {
564
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
565
            write!(f, "U64({:x})", self.0)
566
        }
567
    }
568
569
    impl<E: Endian> fmt::Debug for I16<E> {
570
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
571
            write!(f, "I16({:x})", self.0)
572
        }
573
    }
574
575
    impl<E: Endian> fmt::Debug for I32<E> {
576
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
577
            write!(f, "I32({:x})", self.0)
578
        }
579
    }
580
581
    impl<E: Endian> fmt::Debug for I64<E> {
582
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
583
            write!(f, "I64({:x})", self.0)
584
        }
585
    }
586
587
    unsafe_impl_endian_pod!(U16, U32, U64, I16, I32, I64);
588
}
589
590
#[cfg(not(feature = "unaligned"))]
591
pub use aligned::*;
592
593
/// A `u16` value with an externally specified endianness of type `E`.
594
#[cfg(feature = "unaligned")]
595
pub type U16<E> = U16Bytes<E>;
596
597
/// A `u32` value with an externally specified endianness of type `E`.
598
#[cfg(feature = "unaligned")]
599
pub type U32<E> = U32Bytes<E>;
600
601
/// A `u64` value with an externally specified endianness of type `E`.
602
#[cfg(feature = "unaligned")]
603
pub type U64<E> = U64Bytes<E>;
604
605
/// An `i16` value with an externally specified endianness of type `E`.
606
#[cfg(feature = "unaligned")]
607
pub type I16<E> = I16Bytes<E>;
608
609
/// An `i32` value with an externally specified endianness of type `E`.
610
#[cfg(feature = "unaligned")]
611
pub type I32<E> = I32Bytes<E>;
612
613
/// An `i64` value with an externally specified endianness of type `E`.
614
#[cfg(feature = "unaligned")]
615
pub type I64<E> = I64Bytes<E>;
616
617
/// An unaligned `u16` value with an externally specified endianness of type `E`.
618
#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
619
#[repr(transparent)]
620
pub struct U16Bytes<E: Endian>([u8; 2], PhantomData<E>);
621
622
impl<E: Endian> U16Bytes<E> {
623
    /// Construct a new value given bytes that already have the required endianness.
624
0
    pub fn from_bytes(n: [u8; 2]) -> Self {
625
0
        Self(n, PhantomData)
626
0
    }
627
628
    /// Construct a new value given a native endian value.
629
0
    pub fn new(e: E, n: u16) -> Self {
630
0
        Self(e.write_u16_bytes(n), PhantomData)
631
0
    }
632
633
    /// Return the value as a native endian value.
634
0
    pub fn get(self, e: E) -> u16 {
635
0
        e.read_u16_bytes(self.0)
636
0
    }
Unexecuted instantiation: <object::endian::U16Bytes<object::endian::LittleEndian>>::get
Unexecuted instantiation: <object::endian::U16Bytes<object::endian::LittleEndian>>::get
Unexecuted instantiation: <object::endian::U16Bytes<object::endian::BigEndian>>::get
637
638
    /// Set the value given a native endian value.
639
0
    pub fn set(&mut self, e: E, n: u16) {
640
0
        self.0 = e.write_u16_bytes(n);
641
0
    }
642
}
643
644
/// An unaligned `u32` value with an externally specified endianness of type `E`.
645
#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
646
#[repr(transparent)]
647
pub struct U32Bytes<E: Endian>([u8; 4], PhantomData<E>);
648
649
impl<E: Endian> U32Bytes<E> {
650
    /// Construct a new value given bytes that already have the required endianness.
651
0
    pub fn from_bytes(n: [u8; 4]) -> Self {
652
0
        Self(n, PhantomData)
653
0
    }
654
655
    /// Construct a new value given a native endian value.
656
0
    pub fn new(e: E, n: u32) -> Self {
657
0
        Self(e.write_u32_bytes(n), PhantomData)
658
0
    }
659
660
    /// Return the value as a native endian value.
661
0
    pub fn get(self, e: E) -> u32 {
662
0
        e.read_u32_bytes(self.0)
663
0
    }
Unexecuted instantiation: <object::endian::U32Bytes<object::endian::LittleEndian>>::get
Unexecuted instantiation: <object::endian::U32Bytes<object::endian::BigEndian>>::get
Unexecuted instantiation: <object::endian::U32Bytes<object::endian::BigEndian>>::get
Unexecuted instantiation: <object::endian::U32Bytes<object::endian::LittleEndian>>::get
664
665
    /// Set the value given a native endian value.
666
0
    pub fn set(&mut self, e: E, n: u32) {
667
0
        self.0 = e.write_u32_bytes(n);
668
0
    }
669
}
670
671
/// An unaligned `u64` value with an externally specified endianness of type `E`.
672
#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
673
#[repr(transparent)]
674
pub struct U64Bytes<E: Endian>([u8; 8], PhantomData<E>);
675
676
impl<E: Endian> U64Bytes<E> {
677
    /// Construct a new value given bytes that already have the required endianness.
678
0
    pub fn from_bytes(n: [u8; 8]) -> Self {
679
0
        Self(n, PhantomData)
680
0
    }
681
682
    /// Construct a new value given a native endian value.
683
0
    pub fn new(e: E, n: u64) -> Self {
684
0
        Self(e.write_u64_bytes(n), PhantomData)
685
0
    }
686
687
    /// Return the value as a native endian value.
688
0
    pub fn get(self, e: E) -> u64 {
689
0
        e.read_u64_bytes(self.0)
690
0
    }
Unexecuted instantiation: <object::endian::U64Bytes<object::endian::LittleEndian>>::get
Unexecuted instantiation: <object::endian::U64Bytes<object::endian::BigEndian>>::get
Unexecuted instantiation: <object::endian::U64Bytes<object::endian::LittleEndian>>::get
691
692
    /// Set the value given a native endian value.
693
0
    pub fn set(&mut self, e: E, n: u64) {
694
0
        self.0 = e.write_u64_bytes(n);
695
0
    }
696
}
697
698
/// An unaligned `i16` value with an externally specified endianness of type `E`.
699
#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
700
#[repr(transparent)]
701
pub struct I16Bytes<E: Endian>([u8; 2], PhantomData<E>);
702
703
impl<E: Endian> I16Bytes<E> {
704
    /// Construct a new value given bytes that already have the required endianness.
705
0
    pub fn from_bytes(n: [u8; 2]) -> Self {
706
0
        Self(n, PhantomData)
707
0
    }
708
709
    /// Construct a new value given a native endian value.
710
0
    pub fn new(e: E, n: i16) -> Self {
711
0
        Self(e.write_i16_bytes(n), PhantomData)
712
0
    }
713
714
    /// Return the value as a native endian value.
715
0
    pub fn get(self, e: E) -> i16 {
716
0
        e.read_i16_bytes(self.0)
717
0
    }
718
719
    /// Set the value given a native endian value.
720
0
    pub fn set(&mut self, e: E, n: i16) {
721
0
        self.0 = e.write_i16_bytes(n);
722
0
    }
723
}
724
725
/// An unaligned `i32` value with an externally specified endianness of type `E`.
726
#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
727
#[repr(transparent)]
728
pub struct I32Bytes<E: Endian>([u8; 4], PhantomData<E>);
729
730
impl<E: Endian> I32Bytes<E> {
731
    /// Construct a new value given bytes that already have the required endianness.
732
0
    pub fn from_bytes(n: [u8; 4]) -> Self {
733
0
        Self(n, PhantomData)
734
0
    }
735
736
    /// Construct a new value given a native endian value.
737
0
    pub fn new(e: E, n: i32) -> Self {
738
0
        Self(e.write_i32_bytes(n), PhantomData)
739
0
    }
740
741
    /// Return the value as a native endian value.
742
0
    pub fn get(self, e: E) -> i32 {
743
0
        e.read_i32_bytes(self.0)
744
0
    }
745
746
    /// Set the value given a native endian value.
747
0
    pub fn set(&mut self, e: E, n: i32) {
748
0
        self.0 = e.write_i32_bytes(n);
749
0
    }
750
}
751
752
/// An unaligned `i64` value with an externally specified endianness of type `E`.
753
#[derive(Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
754
#[repr(transparent)]
755
pub struct I64Bytes<E: Endian>([u8; 8], PhantomData<E>);
756
757
impl<E: Endian> I64Bytes<E> {
758
    /// Construct a new value given bytes that already have the required endianness.
759
0
    pub fn from_bytes(n: [u8; 8]) -> Self {
760
0
        Self(n, PhantomData)
761
0
    }
762
763
    /// Construct a new value given a native endian value.
764
0
    pub fn new(e: E, n: i64) -> Self {
765
0
        Self(e.write_i64_bytes(n), PhantomData)
766
0
    }
767
768
    /// Return the value as a native endian value.
769
0
    pub fn get(self, e: E) -> i64 {
770
0
        e.read_i64_bytes(self.0)
771
0
    }
772
773
    /// Set the value given a native endian value.
774
0
    pub fn set(&mut self, e: E, n: i64) {
775
0
        self.0 = e.write_i64_bytes(n);
776
0
    }
777
}
778
779
impl<E: Endian> fmt::Debug for U16Bytes<E> {
780
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
781
0
        write!(f, "U16({:x}, {:x})", self.0[0], self.0[1],)
782
0
    }
Unexecuted instantiation: <object::endian::U16Bytes<object::endian::LittleEndian> as core::fmt::Debug>::fmt
Unexecuted instantiation: <object::endian::U16Bytes<object::endian::BigEndian> as core::fmt::Debug>::fmt
783
}
784
785
impl<E: Endian> fmt::Debug for U32Bytes<E> {
786
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
787
0
        write!(
788
0
            f,
789
0
            "U32({:x}, {:x}, {:x}, {:x})",
790
0
            self.0[0], self.0[1], self.0[2], self.0[3],
791
0
        )
792
0
    }
Unexecuted instantiation: <object::endian::U32Bytes<object::endian::LittleEndian> as core::fmt::Debug>::fmt
Unexecuted instantiation: <object::endian::U32Bytes<object::endian::BigEndian> as core::fmt::Debug>::fmt
793
}
794
795
impl<E: Endian> fmt::Debug for U64Bytes<E> {
796
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
797
0
        write!(
798
0
            f,
799
0
            "U64({:x}, {:x}, {:x}, {:x}, {:x}, {:x}, {:x}, {:x})",
800
0
            self.0[0], self.0[1], self.0[2], self.0[3], self.0[4], self.0[5], self.0[6], self.0[7],
801
0
        )
802
0
    }
Unexecuted instantiation: <object::endian::U64Bytes<object::endian::LittleEndian> as core::fmt::Debug>::fmt
Unexecuted instantiation: <object::endian::U64Bytes<object::endian::BigEndian> as core::fmt::Debug>::fmt
803
}
804
805
impl<E: Endian> fmt::Debug for I16Bytes<E> {
806
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
807
0
        write!(f, "I16({:x}, {:x})", self.0[0], self.0[1],)
808
0
    }
809
}
810
811
impl<E: Endian> fmt::Debug for I32Bytes<E> {
812
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
813
0
        write!(
814
0
            f,
815
0
            "I32({:x}, {:x}, {:x}, {:x})",
816
0
            self.0[0], self.0[1], self.0[2], self.0[3],
817
0
        )
818
0
    }
819
}
820
821
impl<E: Endian> fmt::Debug for I64Bytes<E> {
822
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
823
0
        write!(
824
0
            f,
825
0
            "I64({:x}, {:x}, {:x}, {:x}, {:x}, {:x}, {:x}, {:x})",
826
0
            self.0[0], self.0[1], self.0[2], self.0[3], self.0[4], self.0[5], self.0[6], self.0[7],
827
0
        )
828
0
    }
829
}
830
831
unsafe_impl_endian_pod!(U16Bytes, U32Bytes, U64Bytes, I16Bytes, I32Bytes, I64Bytes);