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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
use TryFromSliceError;
/// Trait for arrays of bytes that may be used in numeric conversions.
///
/// In particular, this is used as a bound for the associated type
/// [`PrimitiveNumber::Bytes`][crate::PrimitiveNumber::Bytes] for converting numbers to and from an
/// array of bytes in various endian orders. It is simply `[u8; size_of::<Self>()]` for every
/// primitive number type, but there's no way yet to write that directly in the trait.
///
/// This trait is not exhaustive of everything byte arrays can do, but it's enough to be useful for
/// generically constructing bytes and dealing with them as slices.
///
/// This trait is sealed with a private trait to prevent downstream implementations, so we may
/// continue to expand along with the standard library without worrying about breaking changes for
/// implementors.
///
/// # Examples
///
/// The supertraits of `PrimitiveBytes` can be used without importing this trait directly:
///
/// ```
/// use num_primitive::PrimitiveNumber;
///
/// // Return a value with the most significant bit set
/// fn msb<T: PrimitiveNumber>() -> T {
/// let mut bytes = T::Bytes::default(); // prelude `Default`
/// bytes[0] = 0x80; // operator `IndexMut`
/// T::from_be_bytes(bytes)
/// }
///
/// assert_eq!(msb::<i64>(), i64::MIN);
/// assert_eq!(msb::<u16>(), 1u16 << 15);
/// assert!(msb::<f64>().total_cmp(&-0.0).is_eq());
/// ```
///
/// However, this trait must be imported to use its own methods like [`repeat`][Self::repeat]:
///
/// ```
/// use num_primitive::{PrimitiveBytes, PrimitiveNumber};
///
/// // Return a value with all bits set
/// fn all_ones<T: PrimitiveNumber>() -> T {
/// T::from_ne_bytes(T::Bytes::repeat(0xff))
/// }
///
/// assert_eq!(all_ones::<i32>(), -1);
/// assert_eq!(all_ones::<usize>(), usize::MAX);
/// assert!(all_ones::<f64>().is_nan());
/// ```
///
/// In cases where the size is known, you can use that as a constraint and then work with byte
/// arrays directly, regardless of this trait.
///
/// ```
/// use num_primitive::PrimitiveNumber;
///
/// fn rust<T: PrimitiveNumber<Bytes = [u8; 4]>>() -> T {
/// T::from_be_bytes(*b"Rust")
/// }
///
/// assert_eq!(rust::<i32>(), 0x52_75_73_74_i32);
/// assert_eq!(rust::<u32>(), 0x52_75_73_74_u32);
/// assert_eq!(rust::<f32>(), 2.63551e11);
/// ```