1use crate::{Bits, BitsWrapper, Error, MutBits};
9
10pub const fn array_concat_1(a: [u8; 1], b: [u8; 1]) -> [u8; 2] {
12 let [a] = a;
13 let [b] = b;
14 [a, b]
15}
16pub const fn array_split_1(a: [u8; 2]) -> ([u8; 1], [u8; 1]) {
18 let [a, b] = a;
19 ([a], [b])
20}
21pub const fn array_concat_2(a: [u8; 2], b: [u8; 2]) -> [u8; 4] {
23 let [c, d] = b;
24 let [a, b] = a;
25 [a, b, c, d]
26}
27pub const fn array_split_2(a: [u8; 4]) -> ([u8; 2], [u8; 2]) {
29 let [a, b, c, d] = a;
30 ([a, b], [c, d])
31}
32pub const fn array_concat_4(a: [u8; 4], b: [u8; 4]) -> [u8; 8] {
34 let [e, f, g, h] = b;
35 let [a, b, c, d] = a;
36 [a, b, c, d, e, f, g, h]
37}
38pub const fn array_split_4(a: [u8; 8]) -> ([u8; 4], [u8; 4]) {
40 let [a, b, c, d, e, f, g, h] = a;
41 ([a, b, c, d], [e, f, g, h])
42}
43pub const fn array_concat_8(a: [u8; 8], b: [u8; 8]) -> [u8; 16] {
45 let [i, j, k, l, m, n, o, p] = b;
46 let [a, b, c, d, e, f, g, h] = a;
47 [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p]
48}
49pub const fn array_split_8(a: [u8; 16]) -> ([u8; 8], [u8; 8]) {
51 let [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p] = a;
52 ([a, b, c, d, e, f, g, h], [i, j, k, l, m, n, o, p])
53}
54pub const fn array_concat_16(a: [u8; 16], b: [u8; 16]) -> [u8; 32] {
56 let [q, r, s, t, u, v, w, x, y, z, aa, ab, ac, ad, ae, af] = b;
57 let [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p] = a;
58 [
59 a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, ab, ac,
60 ad, ae, af,
61 ]
62}
63pub const fn array_split_16(a: [u8; 32]) -> ([u8; 16], [u8; 16]) {
65 let [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, aa, ab, ac, ad, ae, af] =
66 a;
67 (
68 [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p],
69 [q, r, s, t, u, v, w, x, y, z, aa, ab, ac, ad, ae, af],
70 )
71}
72pub trait ToBEBytes<const N: usize> {
74 fn to_be_bytes(&self) -> [u8; N];
75}
76pub trait FromBEBytes<const N: usize> {
78 fn from_be_bytes(bytes: [u8; N]) -> Self;
79}
80pub trait ToLEBytes<const N: usize> {
82 fn to_le_bytes(&self) -> [u8; N];
83}
84pub trait FromLEBytes<const N: usize> {
86 fn from_le_bytes(bytes: [u8; N]) -> Self;
87}
88
89macro_rules! impl_codecs {
90 ($ty:ty, $len:literal, $len2:literal, $arrsplit:ident, $arrconcat:ident, $writebe:ident, $readbe:ident, $writele:ident, $readle:ident) => {
91 impl ToBEBytes<$len> for $ty {
92 fn to_be_bytes(&self) -> [u8; $len] {
93 <$ty>::to_be_bytes(*self)
94 }
95 }
96 impl FromBEBytes<$len> for $ty {
97 fn from_be_bytes(bytes: [u8; $len]) -> $ty {
98 <$ty>::from_be_bytes(bytes)
99 }
100 }
101
102 impl ToLEBytes<$len> for $ty {
103 fn to_le_bytes(&self) -> [u8; $len] {
104 <$ty>::to_le_bytes(*self)
105 }
106 }
107 impl FromLEBytes<$len> for $ty {
108 fn from_le_bytes(bytes: [u8; $len]) -> Self {
109 <$ty>::from_le_bytes(bytes)
110 }
111 }
112 impl WriteToBEBits for $ty {
113 fn write_be_to<T: MutBits + ?Sized>(&self, bits: &mut T) -> Result<usize, Error> {
114 bits.$writebe(*self)?;
115 Ok($len)
116 }
117 }
118 impl WriteToLEBits for $ty {
119 fn write_le_to<T: MutBits + ?Sized>(&self, bits: &mut T) -> Result<usize, Error> {
120 bits.$writele(*self)?;
121 Ok($len)
122 }
123 }
124 impl ReadFromBEBits for $ty {
125 fn read_from_be_bits<T: Bits>(inp: &mut T) -> Result<Self, Error> {
126 inp.$readbe()
127 }
128 }
129 impl ReadFromLEBits for $ty {
130 fn read_from_le_bits<T: Bits>(inp: &mut T) -> Result<Self, Error> {
131 inp.$readle()
132 }
133 }
134
135 impl ToBEBytes<$len2> for [$ty; 2] {
136 fn to_be_bytes(&self) -> [u8; $len2] {
137 let [a, b] = *self;
138 $arrconcat(<$ty>::to_be_bytes(a), <$ty>::to_be_bytes(b))
139 }
140 }
141 impl ToLEBytes<$len2> for [$ty; 2] {
142 fn to_le_bytes(&self) -> [u8; $len2] {
143 let [a, b] = *self;
144 $arrconcat(<$ty>::to_le_bytes(a), <$ty>::to_le_bytes(b))
145 }
146 }
147 impl FromBEBytes<$len2> for [$ty; 2] {
148 fn from_be_bytes(bytes: [u8; $len2]) -> Self {
149 let (a, b) = $arrsplit(bytes);
150 [<$ty>::from_be_bytes(a), <$ty>::from_be_bytes(b)]
151 }
152 }
153 impl FromLEBytes<$len2> for [$ty; 2] {
154 fn from_le_bytes(bytes: [u8; $len2]) -> Self {
155 let (a, b) = $arrsplit(bytes);
156 [<$ty>::from_le_bytes(a), <$ty>::from_le_bytes(b)]
157 }
158 }
159 };
160}
161impl_codecs!(
162 u8,
163 1,
164 2,
165 array_split_1,
166 array_concat_1,
167 write_u8,
168 read_u8,
169 write_u8,
170 read_u8
171);
172impl_codecs!(
173 i8,
174 1,
175 2,
176 array_split_1,
177 array_concat_1,
178 write_i8,
179 read_i8,
180 write_i8,
181 read_i8
182);
183impl_codecs!(
184 u16,
185 2,
186 4,
187 array_split_2,
188 array_concat_2,
189 write_be_u16,
190 read_be_u16,
191 write_le_u16,
192 read_le_u16
193);
194impl_codecs!(
195 i16,
196 2,
197 4,
198 array_split_2,
199 array_concat_2,
200 write_be_i16,
201 read_be_i16,
202 write_le_i16,
203 read_le_i16
204);
205impl_codecs!(
206 u32,
207 4,
208 8,
209 array_split_4,
210 array_concat_4,
211 write_be_u32,
212 read_be_u32,
213 write_le_u32,
214 read_le_u32
215);
216impl_codecs!(
217 i32,
218 4,
219 8,
220 array_split_4,
221 array_concat_4,
222 write_be_i32,
223 read_be_i32,
224 write_le_i32,
225 read_le_i32
226);
227impl_codecs!(
228 f32,
229 4,
230 8,
231 array_split_4,
232 array_concat_4,
233 write_be_f32,
234 read_be_f32,
235 write_le_f32,
236 read_le_f32
237);
238impl_codecs!(
239 u64,
240 8,
241 16,
242 array_split_8,
243 array_concat_8,
244 write_be_u64,
245 read_be_u64,
246 write_le_u64,
247 read_le_u64
248);
249impl_codecs!(
250 i64,
251 8,
252 16,
253 array_split_8,
254 array_concat_8,
255 write_be_i64,
256 read_be_i64,
257 write_le_i64,
258 read_le_i64
259);
260impl_codecs!(
261 f64,
262 8,
263 16,
264 array_split_8,
265 array_concat_8,
266 write_be_f64,
267 read_be_f64,
268 write_le_f64,
269 read_le_f64
270);
271impl_codecs!(
272 u128,
273 16,
274 32,
275 array_split_16,
276 array_concat_16,
277 write_be_u128,
278 read_le_u128,
279 write_le_u128,
280 read_le_u128
281);
282impl_codecs!(
283 i128,
284 16,
285 32,
286 array_split_16,
287 array_concat_16,
288 write_be_i128,
289 read_le_i128,
290 write_le_i128,
291 read_le_i128
292);
293
294macro_rules! impl_large_array {
295 ($ty:ty, $len:literal, $len2:literal, $writebe:ident, $writele:ident, $nextbe:ident, $nextle:ident) => {
296 impl ToBEBytes<$len2> for [$ty; $len] {
297 fn to_be_bytes(&self) -> [u8; $len2] {
298 let mut out = [0u8; $len2];
299 let mut wr = BitsWrapper::Owned(out.as_mut_slice());
300 for v in self {
301 let _ = wr.$writebe(*v);
302 }
303 out
304 }
305 }
306 impl ToLEBytes<$len2> for [$ty; $len] {
307 fn to_le_bytes(&self) -> [u8; $len2] {
308 let mut out = [0u8; $len2];
309 let mut wr = BitsWrapper::Owned(out.as_mut_slice());
310 for v in self {
311 let _ = wr.$writele(*v);
312 }
313 out
314 }
315 }
316 impl FromBEBytes<$len2> for [$ty; $len] {
317 fn from_be_bytes(bytes: [u8; $len2]) -> Self {
318 let mut out = [0; $len];
319 let mut rd = BitsWrapper::Owned(bytes.as_ref());
320 for v in out.iter_mut() {
321 let Ok(Some(a)) = rd.$nextbe() else {
322 break;
323 };
324 *v = a;
325 }
326 out
327 }
328 }
329 impl FromLEBytes<$len2> for [$ty; $len] {
330 fn from_le_bytes(bytes: [u8; $len2]) -> Self {
331 let mut out = [0; $len];
332 let mut rd = BitsWrapper::Owned(bytes.as_ref());
333 for v in out.iter_mut() {
334 let Ok(Some(a)) = rd.$nextle() else {
335 break;
336 };
337 *v = a;
338 }
339 out
340 }
341 }
342 };
343}
344impl_large_array!(
345 u32,
346 3,
347 12,
348 write_be_u32,
349 write_le_u32,
350 next_be_u32,
351 next_le_u32
352); impl_large_array!(
354 u32,
355 4,
356 16,
357 write_be_u32,
358 write_le_u32,
359 next_be_u32,
360 next_le_u32
361); impl_large_array!(
363 u32,
364 5,
365 20,
366 write_be_u32,
367 write_le_u32,
368 next_be_u32,
369 next_le_u32
370); impl_large_array!(
372 u32,
373 6,
374 24,
375 write_be_u32,
376 write_le_u32,
377 next_be_u32,
378 next_le_u32
379); impl_large_array!(
381 u32,
382 7,
383 28,
384 write_be_u32,
385 write_le_u32,
386 next_be_u32,
387 next_le_u32
388); impl_large_array!(
390 u32,
391 8,
392 32,
393 write_be_u32,
394 write_le_u32,
395 next_be_u32,
396 next_le_u32
397); impl_large_array!(
399 u32,
400 9,
401 36,
402 write_be_u32,
403 write_le_u32,
404 next_be_u32,
405 next_le_u32
406); impl_large_array!(
408 u32,
409 10,
410 40,
411 write_be_u32,
412 write_le_u32,
413 next_be_u32,
414 next_le_u32
415); impl_large_array!(
417 u32,
418 11,
419 44,
420 write_be_u32,
421 write_le_u32,
422 next_be_u32,
423 next_le_u32
424); impl_large_array!(
426 u32,
427 12,
428 48,
429 write_be_u32,
430 write_le_u32,
431 next_be_u32,
432 next_le_u32
433); impl_large_array!(
436 u64,
437 3,
438 24,
439 write_be_u64,
440 write_le_u64,
441 next_be_u64,
442 next_le_u64
443); impl_large_array!(
445 u64,
446 4,
447 32,
448 write_be_u64,
449 write_le_u64,
450 next_be_u64,
451 next_le_u64
452); impl_large_array!(
454 u64,
455 5,
456 40,
457 write_be_u64,
458 write_le_u64,
459 next_be_u64,
460 next_le_u64
461); impl_large_array!(
463 u64,
464 6,
465 48,
466 write_be_u64,
467 write_le_u64,
468 next_be_u64,
469 next_le_u64
470); impl_large_array!(
472 u64,
473 7,
474 56,
475 write_be_u64,
476 write_le_u64,
477 next_be_u64,
478 next_le_u64
479); impl_large_array!(
481 u64,
482 8,
483 64,
484 write_be_u64,
485 write_le_u64,
486 next_be_u64,
487 next_le_u64
488); impl_large_array!(
490 u64,
491 9,
492 72,
493 write_be_u64,
494 write_le_u64,
495 next_be_u64,
496 next_le_u64
497); impl_large_array!(
499 u64,
500 10,
501 80,
502 write_be_u64,
503 write_le_u64,
504 next_be_u64,
505 next_le_u64
506); impl_large_array!(
508 u64,
509 11,
510 88,
511 write_be_u64,
512 write_le_u64,
513 next_be_u64,
514 next_le_u64
515); impl_large_array!(
517 u64,
518 12,
519 96,
520 write_be_u64,
521 write_le_u64,
522 next_be_u64,
523 next_le_u64
524); impl_large_array!(
527 u128,
528 3,
529 48,
530 write_be_u128,
531 write_le_u128,
532 next_be_u128,
533 next_le_u128
534); impl_large_array!(
536 u128,
537 4,
538 64,
539 write_be_u128,
540 write_le_u128,
541 next_be_u128,
542 next_le_u128
543); impl_large_array!(
545 u128,
546 5,
547 80,
548 write_be_u128,
549 write_le_u128,
550 next_be_u128,
551 next_le_u128
552); impl_large_array!(
554 u128,
555 6,
556 96,
557 write_be_u128,
558 write_le_u128,
559 next_be_u128,
560 next_le_u128
561); impl_large_array!(
563 u128,
564 7,
565 112,
566 write_be_u128,
567 write_le_u128,
568 next_be_u128,
569 next_le_u128
570); impl_large_array!(
572 u128,
573 8,
574 128,
575 write_be_u128,
576 write_le_u128,
577 next_be_u128,
578 next_le_u128
579); impl_large_array!(
581 u128,
582 9,
583 144,
584 write_be_u128,
585 write_le_u128,
586 next_be_u128,
587 next_le_u128
588); impl_large_array!(
590 u128,
591 10,
592 160,
593 write_be_u128,
594 write_le_u128,
595 next_be_u128,
596 next_le_u128
597); impl_large_array!(
599 u128,
600 11,
601 176,
602 write_be_u128,
603 write_le_u128,
604 next_be_u128,
605 next_le_u128
606); impl_large_array!(
608 u128,
609 12,
610 192,
611 write_be_u128,
612 write_le_u128,
613 next_be_u128,
614 next_le_u128
615); pub trait WriteToBEBits {
619 fn write_be_to<T: MutBits + ?Sized>(&self, bits: &mut T) -> Result<usize, Error>;
620}
621pub trait WriteToLEBits {
623 fn write_le_to<T: MutBits + ?Sized>(&self, bits: &mut T) -> Result<usize, Error>;
624}
625
626pub trait ReadFromBEBits: Sized {
627 fn read_from_be_bits<T: Bits>(inp: &mut T) -> Result<Self, Error>;
628}
629pub trait ReadFromLEBits: Sized {
630 fn read_from_le_bits<T: Bits>(inp: &mut T) -> Result<Self, Error>;
631}
632impl<const N: usize> ReadFromBEBits for [u8; N] {
633 fn read_from_be_bits<T: Bits>(inp: &mut T) -> Result<Self, Error> {
634 let mut out = [0; N];
635 inp.read_all_into(&mut out.as_mut_slice())?;
636 Ok(out)
637 }
638}
639impl<const N: usize> ReadFromLEBits for [u8; N] {
640 fn read_from_le_bits<T: Bits>(inp: &mut T) -> Result<Self, Error> {
641 let mut out = [0; N];
642 inp.read_all_into(&mut out.as_mut_slice())?;
643 Ok(out)
644 }
645}
646
647pub const fn u64_to_u128(val: [u64; 2]) -> u128 {
649 let [a, b] = val;
650 u128::from_be_bytes(array_concat_8(u64::to_be_bytes(a), u64::to_be_bytes(b)))
651}
652pub const fn u32_to_u64(val: [u32; 2]) -> u64 {
654 let [a, b] = val;
655 u64::from_be_bytes(array_concat_4(u32::to_be_bytes(a), u32::to_be_bytes(b)))
656}
657pub const fn u32_to_u128(val: [u32; 4]) -> u128 {
659 let [a, b, c, d] = val;
660 u64_to_u128([u32_to_u64([a, b]), u32_to_u64([c, d])])
661}
662pub const fn u16_to_u32(val: [u16; 2]) -> u32 {
664 let [a, b] = val;
665 u32::from_be_bytes(array_concat_2(u16::to_be_bytes(a), u16::to_be_bytes(b)))
666}
667pub const fn u16_to_u64(val: [u16; 4]) -> u64 {
669 let [a, b, c, d] = val;
670 u32_to_u64([u16_to_u32([a, b]), u16_to_u32([c, d])])
671}
672pub const fn u16_to_u128(val: [u16; 8]) -> u128 {
674 let [a, b, c, d, e, f, g, h] = val;
675 u64_to_u128([u16_to_u64([a, b, c, d]), u16_to_u64([e, f, g, h])])
676}
677
678pub const fn u128_to_u64(val: u128) -> [u64; 2] {
680 let a = val as u64;
681 let b = (val >> 64) as u64;
682 [b, a]
683}
684pub const fn u64_to_u32(val: u64) -> [u32; 2] {
686 let a = val as u32;
687 let b = (val >> 32) as u32;
688 [b, a]
689}
690pub const fn u32_to_u16(val: u32) -> [u16; 2] {
692 let a = val as u16;
693 let b = (val >> 16) as u16;
694 [b, a]
695}
696pub const fn u128_to_u32(val: u128) -> [u32; 4] {
698 let [a, b] = u128_to_u64(val);
699 let [c, d] = u64_to_u32(a);
700 let [e, f] = u64_to_u32(b);
701 [c, d, e, f]
702}
703pub const fn u64_to_u16(val: u64) -> [u16; 4] {
705 let [a, b] = u64_to_u32(val);
706 let [c, d] = u32_to_u16(a);
707 let [e, f] = u32_to_u16(b);
708 [c, d, e, f]
709}
710pub const fn u128_to_u16(val: u128) -> [u16; 8] {
712 let [a, b, c, d] = u128_to_u32(val);
713 let [e, f] = u32_to_u16(a);
714 let [g, h] = u32_to_u16(b);
715 let [i, j] = u32_to_u16(c);
716 let [k, l] = u32_to_u16(d);
717 [e, f, g, h, i, j, k, l]
718}
719
720impl WriteToBEBits for &str {
721 fn write_be_to<T: MutBits + ?Sized>(&self, bits: &mut T) -> Result<usize, Error> {
722 bits.write_str_u32_blob(self)
723 }
724}
725impl WriteToLEBits for &str {
726 fn write_le_to<T: MutBits + ?Sized>(&self, bits: &mut T) -> Result<usize, Error> {
727 let len = self.len() as u32;
728 bits.write_le_u32(len)?;
729 bits.write_all_bytes(self.as_bytes())?;
730
731 Ok((len + 4) as usize)
732 }
733}
734
735cfg_feature_alloc! {
736 extern crate alloc;
737 impl WriteToBEBits for alloc::string::String {
738 fn write_be_to<T: MutBits + ?Sized>(&self, bits: &mut T) -> Result<usize, Error> {
739 bits.write_str_u32_blob(self.as_str())
740 }
741 }
742 impl ReadFromBEBits for alloc::string::String {
743 fn read_from_be_bits<T: Bits>(inp: &mut T) -> Result<Self, Error> {
744 inp.read_str_u32_blob()
745 }
746 }
747 impl ReadFromLEBits for alloc::string::String {
748 fn read_from_le_bits<T: Bits>(inp: &mut T) -> Result<Self, Error> {
749 let len = inp.read_le_u32()?;
750 inp.read_str_sized_lossy(len as usize)
751 }
752 }
753 impl WriteToBEBits for alloc::sync::Arc<alloc::string::String> {
754 fn write_be_to<T: MutBits + ?Sized>(&self, bits: &mut T) -> Result<usize, Error> {
755 bits.write_str_u32_blob(self.as_str())
756 }
757 }
758}