1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
use super::BytesCast;
macro_rules! unaligned {
($Int: ident $BeStruct: ident $LeStruct: ident $NeStruct: ident) => {
unaligned!(@doc $Int $BeStruct from_be_bytes to_be_bytes "Big", "");
unaligned!(@doc $Int $LeStruct from_le_bytes to_le_bytes "Little", "");
unaligned!(@doc $Int $NeStruct from_ne_bytes to_ne_bytes "CPU-native",
"\n\nThe byte order depends on the target CPU architecture.");
};
(
@doc $Int: ident $Struct: ident
$from_bytes: ident $to_bytes: ident
$endian: expr, $extra_doc: expr
) => {
unaligned!(
@def $Int $Struct $from_bytes $to_bytes concat!(
$endian, "-endian `", stringify!($Int), "`, \
without alignment requirement.\n\
\n\
Implements the [`BytesCast`] trait to reinterpret `&[u8]` byte slices, \
and the [`From`] and [`Into`] traits to convert to and from \
`", stringify!($Int), "`.",
$extra_doc
)
);
};
(
@def $Int: ident $Struct: ident
$from_bytes: ident $to_bytes: ident
$doc: expr
) => {
#[derive(BytesCast)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[doc = $doc]
#[repr(transparent)]
pub struct $Struct([u8; ::core::mem::size_of::<$Int>()]);
impl $Struct {
#[inline]
pub fn get(self) -> $Int {
self.into()
}
}
impl From<$Struct> for $Int {
#[inline]
fn from(value: $Struct) -> Self {
$Int::$from_bytes(value.0)
}
}
impl From<$Int> for $Struct {
#[inline]
fn from(value: $Int) -> Self {
Self(value.$to_bytes())
}
}
};
}
unaligned!(u16 U16Be U16Le U16Ne);
unaligned!(u32 U32Be U32Le U32Ne);
unaligned!(u64 U64Be U64Le U64Ne);
unaligned!(u128 U128Be U128Le U128Ne);
unaligned!(i16 I16Be I16Le I16Ne);
unaligned!(i32 I32Be I32Le I32Ne);
unaligned!(i64 I64Be I64Le I64Ne);
unaligned!(i128 I128Be I128Le I128Ne);
unaligned!(f32 F32Be F32Le F32Ne);
unaligned!(f64 F64Be F64Le F64Ne);