devela/num/primitive/
join.rs
1use crate::{paste, Cast};
11
12pub trait PrimitiveJoin<T, U, const LEN: usize> {
24 #[must_use]
26 fn from_array_be(values: [U; LEN]) -> T;
27 #[must_use]
29 fn from_array_le(values: [U; LEN]) -> T;
30 #[must_use]
32 fn from_array_ne(values: [U; LEN]) -> T;
33
34 #[must_use]
36 fn from_slice_be(values: &[U]) -> T;
37 #[must_use]
39 fn from_slice_le(values: &[U]) -> T;
40 #[must_use]
42 fn from_slice_ne(values: &[U]) -> T;
43}
44
45macro_rules! impl_from_trait {
47 ( $( $T:ident, $U:ident, $LEN:literal );+ $(;)? ) => {
48 $( impl_from_trait![@$T, $U, $LEN]; )+
49 };
50 (@$T:ident, $U:ident, $LEN:literal) => { paste! {
51 impl PrimitiveJoin<$T, $U, $LEN> for $T {
52 fn from_array_be(values: [$U; $LEN]) -> $T { Cast::<$T>::[<from_ $U _be>](values) }
53 fn from_array_le(values: [$U; $LEN]) -> $T { Cast::<$T>::[<from_ $U _le>](values) }
54 fn from_array_ne(values: [$U; $LEN]) -> $T { Cast::<$T>::[<from_ $U _ne>](values) }
55 fn from_slice_be(values: &[$U]) -> $T {
56 let mut array = [0; $LEN];
57 for (i, &v) in values.iter().enumerate() {
58 array[i] = v;
59 }
60 Cast::<$T>::[<from_ $U _be>](array)
61 }
62 fn from_slice_le(values: &[$U]) -> $T {
63 let mut array = [0; $LEN];
64 for (i, &v) in values.iter().enumerate() {
65 array[i] = v;
66 }
67 Cast::<$T>::[<from_ $U _le>](array)
68 }
69 fn from_slice_ne(values: &[$U]) -> $T {
70 let mut array = [0; $LEN];
71 for (i, &v) in values.iter().enumerate() {
72 array[i] = v;
73 }
74 Cast::<$T>::[<from_ $U _ne>](array)
75 }
76 }
77 }};
78}
79impl_from_trait![
80 u128, u64, 2; u128, u32, 4; u128, u16, 8; u128, u8, 16;
81 u64, u32, 2; u64, u16, 4; u64, u8, 8;
82 u32, u16, 2; u32, u8, 4;
83 u16, u8, 2;
84];
85
86#[rustfmt::skip]
89#[cfg_attr(feature = "nightly_doc", doc(cfg(feature = "join")))]
90impl Cast<u16> {
91 #[must_use]
93 pub const fn from_u8_be(v: [u8; 2]) -> u16 { u16::from_be_bytes(v) }
94
95 #[must_use]
97 pub const fn from_u8_le(v: [u8; 2]) -> u16 { u16::from_le_bytes(v) }
98
99 #[must_use]
101 pub const fn from_u8_ne(v: [u8; 2]) -> u16 { u16::from_ne_bytes(v) }
102}
103
104#[rustfmt::skip]
105#[cfg_attr(feature = "nightly_doc", doc(cfg(feature = "join")))]
106impl Cast<u32> {
107 #[must_use]
109 pub const fn from_u16_be(v: [u16; 2]) -> u32 {
110 ((v[0] as u32) << 16) | (v[1] as u32)
111 }
112
113 #[must_use]
115 pub const fn from_u16_le(v: [u16; 2]) -> u32 {
116 ((v[1] as u32) << 16) | (v[0] as u32)
117 }
118
119 #[must_use]
121 pub const fn from_u16_ne(v: [u16; 2]) -> u32 {
122 if cfg!(target_endian = "big") {
123 Cast::<u32>::from_u16_be(v)
124 } else {
125 Cast::<u32>::from_u16_le(v)
126 }
127 }
128
129 #[must_use]
131 pub const fn from_u8_be(v: [u8; 4]) -> u32 { u32::from_be_bytes(v) }
132
133 #[must_use]
135 pub const fn from_u8_le(v: [u8; 4]) -> u32 { u32::from_le_bytes(v) }
136
137 #[must_use]
139 pub const fn from_u8_ne(v: [u8; 4]) -> u32 { u32::from_ne_bytes(v) }
140}
141
142#[rustfmt::skip]
143#[cfg_attr(feature = "nightly_doc", doc(cfg(feature = "join")))]
144impl Cast<u64> {
145 #[must_use]
147 pub const fn from_u32_be(v: [u32; 2]) -> u64 {
148 ((v[0] as u64) << 32) | (v[1] as u64)
149 }
150
151 #[must_use]
153 pub const fn from_u32_le(v: [u32; 2]) -> u64 {
154 ((v[1] as u64) << 32) | (v[0] as u64)
155 }
156
157 #[must_use]
159 pub const fn from_u32_ne(v: [u32; 2]) -> u64 {
160 if cfg!(target_endian = "big") {
161 Cast::<u64>::from_u32_be(v)
162 } else {
163 Cast::<u64>::from_u32_le(v)
164 }
165 }
166
167 #[must_use]
169 pub const fn from_u16_be(v: [u16; 4]) -> u64 {
170 ((v[0] as u64) << (16 * 3))
171 | ((v[1] as u64) << (16 * 2))
172 | ((v[2] as u64) << 16)
173 | (v[3] as u64)
174 }
175
176 #[must_use]
178 pub const fn from_u16_le(v: [u16; 4]) -> u64 {
179 ((v[3] as u64) << (16 * 3))
180 | ((v[2] as u64) << (16 * 2))
181 | ((v[1] as u64) << 16)
182 | (v[0] as u64)
183 }
184
185 #[must_use]
187 pub const fn from_u16_ne(v: [u16; 4]) -> u64 {
188 if cfg!(target_endian = "big") {
189 Cast::<u64>::from_u16_be(v)
190 } else {
191 Cast::<u64>::from_u16_le(v)
192 }
193 }
194
195 #[must_use]
197 pub const fn from_u8_be(v: [u8; 8]) -> u64 { u64::from_be_bytes(v) }
198
199 #[must_use]
201 pub const fn from_u8_le(v: [u8; 8]) -> u64 { u64::from_le_bytes(v) }
202
203 #[must_use]
205 pub const fn from_u8_ne(v: [u8; 8]) -> u64 { u64::from_ne_bytes(v) }
206}
207
208#[rustfmt::skip]
209#[cfg_attr(feature = "nightly_doc", doc(cfg(feature = "join")))]
210impl Cast<u128> {
211 #[must_use]
213 pub const fn from_u64_be(v: [u64; 2]) -> u128 {
214 ((v[0] as u128) << 64) | (v[1] as u128)
215 }
216
217 #[must_use]
219 pub const fn from_u64_le(v: [u64; 2]) -> u128 {
220 ((v[1] as u128) << 64) | (v[0] as u128)
221 }
222
223 #[must_use]
225 pub const fn from_u64_ne(v: [u64; 2]) -> u128 {
226 if cfg!(target_endian = "big") {
227 Cast::<u128>::from_u64_be(v)
228 } else {
229 Cast::<u128>::from_u64_le(v)
230 }
231 }
232
233 #[must_use]
235 pub const fn from_u32_be(v: [u32; 4]) -> u128 {
236 ((v[0] as u128) << (32 * 3))
237 | ((v[1] as u128) << (32 * 2))
238 | ((v[2] as u128) << 32)
239 | (v[3] as u128)
240 }
241
242 #[must_use]
244 pub const fn from_u32_le(v: [u32; 4]) -> u128 {
245 ((v[3] as u128) << (32 * 3))
246 | ((v[2] as u128) << (32 * 2))
247 | ((v[1] as u128) << 32)
248 | (v[0] as u128)
249 }
250
251 #[must_use]
253 pub const fn from_u32_ne(v: [u32; 4]) -> u128 {
254 if cfg!(target_endian = "big") {
255 Cast::<u128>::from_u32_be(v)
256 } else {
257 Cast::<u128>::from_u32_le(v)
258 }
259 }
260
261 #[must_use]
263 pub const fn from_u16_be(v: [u16; 8]) -> u128 {
264 ((v[0] as u128) << (16 * 7))
265 | ((v[1] as u128) << (16 * 6))
266 | ((v[2] as u128) << (16 * 5))
267 | ((v[3] as u128) << (16 * 4))
268 | ((v[4] as u128) << (16 * 3))
269 | ((v[5] as u128) << (16 * 2))
270 | ((v[6] as u128) << 16)
271 | (v[7] as u128)
272 }
273
274 #[must_use]
276 pub const fn from_u16_le(v: [u16; 8]) -> u128 {
277 ((v[7] as u128) << (16 * 7))
278 | ((v[6] as u128) << (16 * 6))
279 | ((v[5] as u128) << (16 * 5))
280 | ((v[4] as u128) << (16 * 4))
281 | ((v[3] as u128) << (16 * 3))
282 | ((v[2] as u128) << (16 * 2))
283 | ((v[1] as u128) << 16)
284 | (v[0] as u128)
285 }
286
287 #[must_use]
289 pub const fn from_u16_ne(v: [u16; 8]) -> u128 {
290 if cfg!(target_endian = "big") {
291 Cast::<u128>::from_u16_be(v)
292 } else {
293 Cast::<u128>::from_u16_le(v)
294 }
295 }
296
297 #[must_use]
299 pub const fn from_u8_be(v: [u8; 16]) -> u128 { u128::from_be_bytes(v) }
300
301 #[must_use]
303 pub const fn from_u8_le(v: [u8; 16]) -> u128 { u128::from_le_bytes(v) }
304
305 #[must_use]
307 pub const fn from_u8_ne(v: [u8; 16]) -> u128 { u128::from_ne_bytes(v) }
308}