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 u32,
437 16,
438 64,
439 write_be_u32,
440 write_le_u32,
441 next_be_u32,
442 next_le_u32
443); impl_large_array!(
446 u64,
447 3,
448 24,
449 write_be_u64,
450 write_le_u64,
451 next_be_u64,
452 next_le_u64
453); impl_large_array!(
455 u64,
456 4,
457 32,
458 write_be_u64,
459 write_le_u64,
460 next_be_u64,
461 next_le_u64
462); impl_large_array!(
464 u64,
465 5,
466 40,
467 write_be_u64,
468 write_le_u64,
469 next_be_u64,
470 next_le_u64
471); impl_large_array!(
473 u64,
474 6,
475 48,
476 write_be_u64,
477 write_le_u64,
478 next_be_u64,
479 next_le_u64
480); impl_large_array!(
482 u64,
483 7,
484 56,
485 write_be_u64,
486 write_le_u64,
487 next_be_u64,
488 next_le_u64
489); impl_large_array!(
491 u64,
492 8,
493 64,
494 write_be_u64,
495 write_le_u64,
496 next_be_u64,
497 next_le_u64
498); impl_large_array!(
500 u64,
501 9,
502 72,
503 write_be_u64,
504 write_le_u64,
505 next_be_u64,
506 next_le_u64
507); impl_large_array!(
509 u64,
510 10,
511 80,
512 write_be_u64,
513 write_le_u64,
514 next_be_u64,
515 next_le_u64
516); impl_large_array!(
518 u64,
519 11,
520 88,
521 write_be_u64,
522 write_le_u64,
523 next_be_u64,
524 next_le_u64
525); impl_large_array!(
527 u64,
528 12,
529 96,
530 write_be_u64,
531 write_le_u64,
532 next_be_u64,
533 next_le_u64
534); impl_large_array!(
537 u128,
538 3,
539 48,
540 write_be_u128,
541 write_le_u128,
542 next_be_u128,
543 next_le_u128
544); impl_large_array!(
546 u128,
547 4,
548 64,
549 write_be_u128,
550 write_le_u128,
551 next_be_u128,
552 next_le_u128
553); impl_large_array!(
555 u128,
556 5,
557 80,
558 write_be_u128,
559 write_le_u128,
560 next_be_u128,
561 next_le_u128
562); impl_large_array!(
564 u128,
565 6,
566 96,
567 write_be_u128,
568 write_le_u128,
569 next_be_u128,
570 next_le_u128
571); impl_large_array!(
573 u128,
574 7,
575 112,
576 write_be_u128,
577 write_le_u128,
578 next_be_u128,
579 next_le_u128
580); impl_large_array!(
582 u128,
583 8,
584 128,
585 write_be_u128,
586 write_le_u128,
587 next_be_u128,
588 next_le_u128
589); impl_large_array!(
591 u128,
592 9,
593 144,
594 write_be_u128,
595 write_le_u128,
596 next_be_u128,
597 next_le_u128
598); impl_large_array!(
600 u128,
601 10,
602 160,
603 write_be_u128,
604 write_le_u128,
605 next_be_u128,
606 next_le_u128
607); impl_large_array!(
609 u128,
610 11,
611 176,
612 write_be_u128,
613 write_le_u128,
614 next_be_u128,
615 next_le_u128
616); impl_large_array!(
618 u128,
619 12,
620 192,
621 write_be_u128,
622 write_le_u128,
623 next_be_u128,
624 next_le_u128
625); macro_rules! impl_tobe_self {
628 ($($n:literal) +) => {
629 $(
630 impl ToBEBytes<$n> for [u8;$n] {
631 fn to_be_bytes(&self) -> [u8; $n] {
632 *self
633 }
634 }
635 )*
636 };
637}
638impl_tobe_self!(16 20 28 32 48 60 64);
639
640pub trait WriteToBEBits {
642 fn write_be_to<T: MutBits + ?Sized>(&self, bits: &mut T) -> Result<usize, Error>;
643}
644pub trait WriteToLEBits {
646 fn write_le_to<T: MutBits + ?Sized>(&self, bits: &mut T) -> Result<usize, Error>;
647}
648
649pub trait ReadFromBEBits: Sized {
650 fn read_from_be_bits<T: Bits>(inp: &mut T) -> Result<Self, Error>;
651}
652pub trait ReadFromLEBits: Sized {
653 fn read_from_le_bits<T: Bits>(inp: &mut T) -> Result<Self, Error>;
654}
655impl<const N: usize> ReadFromBEBits for [u8; N] {
656 fn read_from_be_bits<T: Bits>(inp: &mut T) -> Result<Self, Error> {
657 let mut out = [0; N];
658 inp.read_all_into(&mut out.as_mut_slice())?;
659 Ok(out)
660 }
661}
662impl<const N: usize> ReadFromLEBits for [u8; N] {
663 fn read_from_le_bits<T: Bits>(inp: &mut T) -> Result<Self, Error> {
664 let mut out = [0; N];
665 inp.read_all_into(&mut out.as_mut_slice())?;
666 Ok(out)
667 }
668}
669
670pub const fn u64_to_u128(val: [u64; 2]) -> u128 {
672 let [a, b] = val;
673 u128::from_be_bytes(array_concat_8(u64::to_be_bytes(a), u64::to_be_bytes(b)))
674}
675pub const fn u32_to_u64(val: [u32; 2]) -> u64 {
677 let [a, b] = val;
678 u64::from_be_bytes(array_concat_4(u32::to_be_bytes(a), u32::to_be_bytes(b)))
679}
680pub const fn u32_to_u128(val: [u32; 4]) -> u128 {
682 let [a, b, c, d] = val;
683 u64_to_u128([u32_to_u64([a, b]), u32_to_u64([c, d])])
684}
685pub const fn u16_to_u32(val: [u16; 2]) -> u32 {
687 let [a, b] = val;
688 u32::from_be_bytes(array_concat_2(u16::to_be_bytes(a), u16::to_be_bytes(b)))
689}
690pub const fn u16_to_u64(val: [u16; 4]) -> u64 {
692 let [a, b, c, d] = val;
693 u32_to_u64([u16_to_u32([a, b]), u16_to_u32([c, d])])
694}
695pub const fn u16_to_u128(val: [u16; 8]) -> u128 {
697 let [a, b, c, d, e, f, g, h] = val;
698 u64_to_u128([u16_to_u64([a, b, c, d]), u16_to_u64([e, f, g, h])])
699}
700
701pub const fn u128_to_u64(val: u128) -> [u64; 2] {
703 let a = val as u64;
704 let b = (val >> 64) as u64;
705 [b, a]
706}
707pub const fn u64_to_u32(val: u64) -> [u32; 2] {
709 let a = val as u32;
710 let b = (val >> 32) as u32;
711 [b, a]
712}
713pub const fn u32_to_u16(val: u32) -> [u16; 2] {
715 let a = val as u16;
716 let b = (val >> 16) as u16;
717 [b, a]
718}
719pub const fn u128_to_u32(val: u128) -> [u32; 4] {
721 let [a, b] = u128_to_u64(val);
722 let [c, d] = u64_to_u32(a);
723 let [e, f] = u64_to_u32(b);
724 [c, d, e, f]
725}
726pub const fn u64_to_u16(val: u64) -> [u16; 4] {
728 let [a, b] = u64_to_u32(val);
729 let [c, d] = u32_to_u16(a);
730 let [e, f] = u32_to_u16(b);
731 [c, d, e, f]
732}
733pub const fn u128_to_u16(val: u128) -> [u16; 8] {
735 let [a, b, c, d] = u128_to_u32(val);
736 let [e, f] = u32_to_u16(a);
737 let [g, h] = u32_to_u16(b);
738 let [i, j] = u32_to_u16(c);
739 let [k, l] = u32_to_u16(d);
740 [e, f, g, h, i, j, k, l]
741}
742
743impl WriteToBEBits for &str {
744 fn write_be_to<T: MutBits + ?Sized>(&self, bits: &mut T) -> Result<usize, Error> {
745 bits.write_str_u32_blob(self)
746 }
747}
748impl WriteToLEBits for &str {
749 fn write_le_to<T: MutBits + ?Sized>(&self, bits: &mut T) -> Result<usize, Error> {
750 let len = self.len() as u32;
751 bits.write_le_u32(len)?;
752 bits.write_all_bytes(self.as_bytes())?;
753
754 Ok((len + 4) as usize)
755 }
756}
757impl WriteToBEBits for &[u8] {
758 fn write_be_to<T: MutBits + ?Sized>(&self, bits: &mut T) -> Result<usize, Error> {
759 bits.write_all_bytes(self)?;
760 Ok(self.len())
761 }
762}
763
764cfg_feature_alloc! {
765 extern crate alloc;
766 impl WriteToBEBits for alloc::string::String {
767 fn write_be_to<T: MutBits + ?Sized>(&self, bits: &mut T) -> Result<usize, Error> {
768 bits.write_str_u32_blob(self.as_str())
769 }
770 }
771 impl ReadFromBEBits for alloc::string::String {
772 fn read_from_be_bits<T: Bits>(inp: &mut T) -> Result<Self, Error> {
773 inp.read_str_u32_blob()
774 }
775 }
776 impl ReadFromLEBits for alloc::string::String {
777 fn read_from_le_bits<T: Bits>(inp: &mut T) -> Result<Self, Error> {
778 let len = inp.read_le_u32()?;
779 inp.read_str_sized_lossy(len as usize)
780 }
781 }
782 impl WriteToBEBits for alloc::sync::Arc<alloc::string::String> {
783 fn write_be_to<T: MutBits + ?Sized>(&self, bits: &mut T) -> Result<usize, Error> {
784 bits.write_str_u32_blob(self.as_str())
785 }
786 }
787 impl WriteToBEBits for alloc::boxed::Box<[u8]> {
788 fn write_be_to<T: MutBits + ?Sized>(&self, bits: &mut T) -> Result<usize, Error> {
789 bits.write_all_bytes(self)?;
790 Ok(self.len())
791 }
792 }
793}
794
795pub trait SerializeToBits {
797 fn serialize_to_bits<T: MutBits + ?Sized>(&self, bits: &mut T) -> Result<usize, Error>;
798}
799
800pub trait DeserializeFromBits {
802 type Output: Sized;
803 fn deserialize_from_bits<T: Bits>(inp: &mut T) -> Result<Self::Output, Error>;
804}