1use crate::error::Error;
4#[cfg(not(feature = "std"))]
5use alloc::{sync::Arc, vec::Vec};
6use bytes::{Buf, BufMut, Bytes, BytesMut};
7#[cfg(feature = "std")]
8use std::{sync::Arc, vec::Vec};
9
10pub trait FixedSize {
17 const SIZE: usize;
19}
20
21pub trait EncodeSize {
27 fn encode_size(&self) -> usize;
29
30 #[doc(hidden)]
45 #[inline]
46 fn encode_size_slice(values: &[Self]) -> usize
47 where
48 Self: Sized,
49 {
50 values.iter().map(EncodeSize::encode_size).sum()
51 }
52
53 #[inline]
58 fn encode_inline_size(&self) -> usize {
59 self.encode_size()
60 }
61
62 #[doc(hidden)]
76 #[inline]
77 fn encode_inline_size_slice(values: &[Self]) -> usize
78 where
79 Self: Sized,
80 {
81 values
82 .iter()
83 .map(EncodeSize::encode_inline_size)
84 .sum::<usize>()
85 }
86}
87
88impl<T: FixedSize> EncodeSize for T {
90 #[inline]
91 fn encode_size(&self) -> usize {
92 Self::SIZE
93 }
94
95 #[inline]
96 fn encode_size_slice(values: &[Self]) -> usize
97 where
98 Self: Sized,
99 {
100 Self::SIZE * values.len()
101 }
102
103 #[inline]
104 fn encode_inline_size_slice(values: &[Self]) -> usize
105 where
106 Self: Sized,
107 {
108 Self::encode_size_slice(values)
109 }
110}
111
112pub trait Write {
114 fn write(&self, buf: &mut impl BufMut);
118
119 #[doc(hidden)]
132 #[inline]
133 fn write_slice(values: &[Self], buf: &mut impl BufMut)
134 where
135 Self: Sized,
136 {
137 for item in values {
138 item.write(buf);
139 }
140 }
141
142 #[inline]
146 fn write_bufs(&self, buf: &mut impl BufsMut) {
147 self.write(buf);
148 }
149
150 #[doc(hidden)]
161 #[inline]
162 fn write_slice_bufs(values: &[Self], buf: &mut impl BufsMut)
163 where
164 Self: Sized,
165 {
166 for item in values {
167 item.write_bufs(buf);
168 }
169 }
170}
171
172impl<T: EncodeSize + ?Sized> EncodeSize for Arc<T> {
173 #[inline]
174 fn encode_size(&self) -> usize {
175 self.as_ref().encode_size()
176 }
177
178 #[inline]
179 fn encode_inline_size(&self) -> usize {
180 self.as_ref().encode_inline_size()
181 }
182}
183
184impl<T: Write + ?Sized> Write for Arc<T> {
185 #[inline]
186 fn write(&self, buf: &mut impl BufMut) {
187 self.as_ref().write(buf);
188 }
189
190 #[inline]
191 fn write_bufs(&self, buf: &mut impl BufsMut) {
192 self.as_ref().write_bufs(buf);
193 }
194}
195
196pub trait Read: Sized {
198 type Cfg: Clone + Send + Sync + 'static;
204
205 fn read_cfg(buf: &mut impl Buf, cfg: &Self::Cfg) -> Result<Self, Error>;
213
214 #[doc(hidden)]
226 #[inline]
227 fn read_vec(buf: &mut impl Buf, len: usize, cfg: &Self::Cfg) -> Result<Vec<Self>, Error> {
228 let mut values = Vec::with_capacity(len);
229 for _ in 0..len {
230 values.push(Self::read_cfg(buf, cfg)?);
231 }
232 Ok(values)
233 }
234
235 #[doc(hidden)]
245 #[inline]
246 fn read_array<const N: usize>(buf: &mut impl Buf, cfg: &Self::Cfg) -> Result<[Self; N], Error> {
247 Ok(Self::read_vec(buf, N, cfg)?
248 .try_into()
249 .unwrap_or_else(|_| unreachable!("array length should match capacity")))
250 }
251}
252
253pub trait Encode: Write + EncodeSize {
258 fn encode(&self) -> Bytes {
269 self.encode_mut().freeze()
270 }
271
272 fn encode_mut(&self) -> BytesMut {
283 let len = self.encode_size();
284 let mut buffer = BytesMut::with_capacity(len);
285 self.write(&mut buffer);
286 assert_eq!(buffer.len(), len, "write() did not write expected bytes");
287 buffer
288 }
289}
290
291impl<T: Write + EncodeSize> Encode for T {}
293
294pub trait EncodeShared: Encode + Send + Sync {}
298
299impl<T: Encode + Send + Sync> EncodeShared for T {}
301
302pub trait Decode: Read {
306 fn decode_cfg(mut buf: impl Buf, cfg: &Self::Cfg) -> Result<Self, Error> {
311 let result = Self::read_cfg(&mut buf, cfg)?;
312
313 let remaining = buf.remaining();
315 if remaining > 0 {
316 return Err(Error::ExtraData(remaining));
317 }
318
319 Ok(result)
320 }
321}
322
323impl<T: Read> Decode for T {}
325
326pub trait Codec: Encode + Decode {}
330
331impl<T: Encode + Decode> Codec for T {}
333
334pub trait EncodeFixed: Write + FixedSize {
336 fn encode_fixed<const N: usize>(&self) -> [u8; N] {
343 assert_eq!(
346 N,
347 Self::SIZE,
348 "Can't encode {} bytes into {} bytes",
349 Self::SIZE,
350 N
351 );
352
353 let mut array = [0u8; N];
354 let mut buf = &mut array[..];
355 self.write(&mut buf);
356 assert_eq!(buf.len(), 0);
357 array
358 }
359}
360
361impl<T: Write + FixedSize> EncodeFixed for T {}
363
364pub trait DecodeFixed: Read<Cfg = ()> + FixedSize {
366 fn decode_fixed<const N: usize>(bytes: [u8; N]) -> Result<Self, Error> {
372 assert_eq!(
373 N,
374 Self::SIZE,
375 "Can't decode {} bytes into {} bytes",
376 N,
377 Self::SIZE
378 );
379
380 Self::decode_cfg(bytes.as_ref(), &())
381 }
382}
383
384impl<T: Read<Cfg = ()> + FixedSize> DecodeFixed for T {}
386
387pub trait CodecFixed: Codec + FixedSize {}
391
392impl<T: Codec + FixedSize> CodecFixed for T {}
394
395pub trait CodecShared: Codec + Send + Sync {}
399
400impl<T: Codec + Send + Sync> CodecShared for T {}
402
403pub trait CodecFixedShared: CodecFixed<Cfg = ()> + Send + Sync {}
408
409impl<T: CodecFixed<Cfg = ()> + Send + Sync> CodecFixedShared for T {}
411
412pub trait BufsMut: BufMut {
414 fn push(&mut self, bytes: impl Into<Bytes>);
417}
418
419#[cfg(test)]
420mod tests {
421 use super::*;
422 use crate::{
423 extensions::{DecodeExt, ReadExt},
424 Error, FixedArray,
425 };
426 use bytes::Bytes;
427 use core::marker::PhantomData;
428
429 #[test]
430 fn test_insufficient_buffer() {
431 let mut reader = Bytes::from_static(&[0x01, 0x02]);
432 assert!(matches!(u32::read(&mut reader), Err(Error::EndOfBuffer)));
433 }
434
435 #[test]
436 fn test_extra_data() {
437 let encoded = Bytes::from_static(&[0x01, 0x02]);
438 assert!(matches!(u8::decode(encoded), Err(Error::ExtraData(1))));
439 }
440
441 #[test]
442 fn test_encode_fixed() {
443 let value = 42u32;
444 let encoded: [u8; 4] = value.encode_fixed();
445 let decoded = <u32>::decode(&encoded[..]).unwrap();
446 assert_eq!(value, decoded);
447 }
448
449 #[test]
450 fn test_arc_encode() {
451 let value = Arc::new(vec![1u8, 2, 3]);
452
453 assert_eq!(value.encode(), value.as_ref().encode());
454 assert_eq!(value.encode_size(), value.as_ref().encode_size());
455 }
456
457 #[test]
458 #[should_panic(expected = "Can't encode 4 bytes into 5 bytes")]
459 fn test_encode_fixed_panic() {
460 let _: [u8; 5] = 42u32.encode_fixed();
461 }
462
463 #[derive(Debug, Eq, PartialEq, FixedArray)]
464 struct FixedBytes([u8; 2]);
465
466 impl Write for FixedBytes {
467 fn write(&self, buf: &mut impl BufMut) {
468 self.0.write(buf);
469 }
470 }
471
472 impl Read for FixedBytes {
473 type Cfg = ();
474
475 fn read_cfg(buf: &mut impl Buf, _: &()) -> Result<Self, Error> {
476 Ok(Self(<[u8; Self::SIZE]>::read(buf)?))
477 }
478 }
479
480 impl FixedSize for FixedBytes {
481 const SIZE: usize = 2;
482 }
483
484 #[test]
485 fn test_fixed_array() {
486 let value = FixedBytes([1, 2]);
487 let encoded: [u8; FixedBytes::SIZE] = (&value).into();
488 assert_eq!(encoded, [1, 2]);
489 assert_eq!(<[u8; FixedBytes::SIZE]>::from(value), encoded);
490 assert_eq!(FixedBytes::try_from(encoded).unwrap(), FixedBytes([1, 2]));
491 assert_eq!(FixedBytes::try_from(&encoded).unwrap(), FixedBytes([1, 2]));
492 assert_eq!(
493 FixedBytes::try_from([1u8, 2].as_slice()).unwrap(),
494 FixedBytes([1, 2])
495 );
496 assert!(matches!(
497 FixedBytes::try_from([1u8].as_slice()),
498 Err(Error::EndOfBuffer)
499 ));
500 assert!(matches!(
501 FixedBytes::try_from([1u8, 2, 3].as_slice()),
502 Err(Error::ExtraData(1))
503 ));
504 }
505
506 #[test]
507 fn test_decode_fixed() {
508 assert_eq!(
509 FixedBytes::decode_fixed([1, 2]).unwrap(),
510 FixedBytes([1, 2])
511 );
512 }
513
514 #[test]
515 #[should_panic(expected = "Can't decode 3 bytes into 2 bytes")]
516 fn test_decode_fixed_panic() {
517 let _ = FixedBytes::decode_fixed([1, 2, 3]);
518 }
519
520 #[derive(Debug, Eq, PartialEq, FixedArray)]
521 #[fixed_array(infallible)]
522 struct InfallibleFixedBytes([u8; 2]);
523
524 impl Write for InfallibleFixedBytes {
525 fn write(&self, buf: &mut impl BufMut) {
526 self.0.write(buf);
527 }
528 }
529
530 impl Read for InfallibleFixedBytes {
531 type Cfg = ();
532
533 fn read_cfg(buf: &mut impl Buf, _: &()) -> Result<Self, Error> {
534 Ok(Self(<[u8; Self::SIZE]>::read(buf)?))
535 }
536 }
537
538 impl FixedSize for InfallibleFixedBytes {
539 const SIZE: usize = 2;
540 }
541
542 #[test]
543 fn test_fixed_array_infallible() {
544 let value = InfallibleFixedBytes([1, 2]);
545 let encoded: [u8; InfallibleFixedBytes::SIZE] = (&value).into();
546 assert_eq!(encoded, [1, 2]);
547 assert_eq!(<[u8; InfallibleFixedBytes::SIZE]>::from(value), encoded);
548 assert_eq!(
549 InfallibleFixedBytes::from(encoded),
550 InfallibleFixedBytes([1, 2])
551 );
552 assert_eq!(
553 InfallibleFixedBytes::from(&encoded),
554 InfallibleFixedBytes([1, 2])
555 );
556 assert_eq!(
557 InfallibleFixedBytes::try_from([1u8, 2].as_slice()).unwrap(),
558 InfallibleFixedBytes([1, 2])
559 );
560 assert!(matches!(
561 InfallibleFixedBytes::try_from([1u8, 2, 3].as_slice()),
562 Err(Error::ExtraData(1))
563 ));
564 }
565
566 #[derive(Debug, Eq, PartialEq, FixedArray)]
567 #[fixed_array(bytes([u8; N]))]
568 struct GenericFixed<const N: usize>([u8; N]);
569
570 impl<const N: usize> Write for GenericFixed<N> {
571 fn write(&self, buf: &mut impl BufMut) {
572 self.0.write(buf);
573 }
574 }
575
576 impl<const N: usize> Read for GenericFixed<N> {
577 type Cfg = ();
578
579 fn read_cfg(buf: &mut impl Buf, _: &()) -> Result<Self, Error> {
580 Ok(Self(<[u8; N]>::read(buf)?))
581 }
582 }
583
584 impl<const N: usize> FixedSize for GenericFixed<N> {
585 const SIZE: usize = N;
586 }
587
588 #[test]
589 fn test_fixed_array_generic() {
590 let value = GenericFixed::<3>([1, 2, 3]);
591 let encoded: [u8; 3] = (&value).into();
592 assert_eq!(encoded, [1, 2, 3]);
593 assert_eq!(<[u8; 3]>::from(value), encoded);
594 assert_eq!(
595 GenericFixed::<3>::try_from(encoded).unwrap(),
596 GenericFixed([1, 2, 3])
597 );
598 assert_eq!(
599 GenericFixed::<3>::try_from(&encoded).unwrap(),
600 GenericFixed([1, 2, 3])
601 );
602 assert_eq!(
603 GenericFixed::<3>::try_from([1u8, 2, 3].as_slice()).unwrap(),
604 GenericFixed([1, 2, 3])
605 );
606 }
607
608 #[derive(Debug, Eq, PartialEq, FixedArray)]
609 #[fixed_array(infallible, bytes([u8; N]))]
610 struct GenericInfallible<const N: usize>([u8; N]);
611
612 impl<const N: usize> Write for GenericInfallible<N> {
613 fn write(&self, buf: &mut impl BufMut) {
614 self.0.write(buf);
615 }
616 }
617
618 impl<const N: usize> Read for GenericInfallible<N> {
619 type Cfg = ();
620
621 fn read_cfg(buf: &mut impl Buf, _: &()) -> Result<Self, Error> {
622 Ok(Self(<[u8; N]>::read(buf)?))
623 }
624 }
625
626 impl<const N: usize> FixedSize for GenericInfallible<N> {
627 const SIZE: usize = N;
628 }
629
630 #[test]
631 fn test_fixed_array_generic_infallible() {
632 let value = GenericInfallible::<3>([1, 2, 3]);
633 let encoded: [u8; 3] = (&value).into();
634 assert_eq!(encoded, [1, 2, 3]);
635 assert_eq!(<[u8; 3]>::from(value), encoded);
636 assert_eq!(
637 GenericInfallible::<3>::from(encoded),
638 GenericInfallible([1, 2, 3])
639 );
640 assert_eq!(
641 GenericInfallible::<3>::from(&encoded),
642 GenericInfallible([1, 2, 3])
643 );
644 assert_eq!(
645 GenericInfallible::<3>::try_from([1u8, 2, 3].as_slice()).unwrap(),
646 GenericInfallible([1, 2, 3])
647 );
648 }
649
650 trait FixedArrayBound {}
651
652 #[derive(Debug, Eq, PartialEq)]
653 struct Bounded;
654
655 impl FixedArrayBound for Bounded {}
656
657 #[derive(Debug, Eq, PartialEq, FixedArray)]
658 #[fixed_array(bytes([u8; 2]))]
659 struct BoundedGeneric<T> {
660 marker: PhantomData<T>,
661 raw: [u8; 2],
662 }
663
664 impl<T: FixedArrayBound> Write for BoundedGeneric<T> {
665 fn write(&self, buf: &mut impl BufMut) {
666 self.raw.write(buf);
667 }
668 }
669
670 impl<T: FixedArrayBound> Read for BoundedGeneric<T> {
671 type Cfg = ();
672
673 fn read_cfg(buf: &mut impl Buf, _: &()) -> Result<Self, Error> {
674 Ok(Self {
675 marker: PhantomData,
676 raw: <[u8; 2]>::read(buf)?,
677 })
678 }
679 }
680
681 impl<T: FixedArrayBound> FixedSize for BoundedGeneric<T> {
682 const SIZE: usize = 2;
683 }
684
685 #[test]
686 fn test_fixed_array_bounded_generic() {
687 let value = BoundedGeneric::<Bounded> {
688 marker: PhantomData,
689 raw: [1, 2],
690 };
691 let encoded: [u8; 2] = (&value).into();
692 assert_eq!(encoded, [1, 2]);
693 assert_eq!(<[u8; 2]>::from(value).as_ref(), &[1, 2]);
694 assert_eq!(
695 BoundedGeneric::<Bounded>::try_from(encoded).unwrap().raw,
696 [1, 2]
697 );
698 assert_eq!(
699 BoundedGeneric::<Bounded>::try_from(&encoded).unwrap().raw,
700 [1, 2]
701 );
702 assert_eq!(
703 BoundedGeneric::<Bounded>::try_from([1u8, 2].as_slice())
704 .unwrap()
705 .raw,
706 [1, 2]
707 );
708 }
709
710 #[derive(Debug, Eq, PartialEq, FixedArray)]
711 #[fixed_array(bytes([u8; 2]))]
712 struct LifetimeFixed<'a> {
713 marker: PhantomData<&'a ()>,
714 raw: [u8; 2],
715 }
716
717 impl Write for LifetimeFixed<'_> {
718 fn write(&self, buf: &mut impl BufMut) {
719 self.raw.write(buf);
720 }
721 }
722
723 impl Read for LifetimeFixed<'_> {
724 type Cfg = ();
725
726 fn read_cfg(buf: &mut impl Buf, _: &()) -> Result<Self, Error> {
727 Ok(Self {
728 marker: PhantomData,
729 raw: <[u8; 2]>::read(buf)?,
730 })
731 }
732 }
733
734 impl FixedSize for LifetimeFixed<'_> {
735 const SIZE: usize = 2;
736 }
737
738 #[test]
739 fn test_fixed_array_lifetime() {
740 let value = LifetimeFixed {
741 marker: PhantomData,
742 raw: [1, 2],
743 };
744 let encoded: [u8; LifetimeFixed::SIZE] = (&value).into();
745 assert_eq!(encoded, [1, 2]);
746 assert_eq!(<[u8; LifetimeFixed::SIZE]>::from(value).as_ref(), &[1, 2]);
747 assert_eq!(LifetimeFixed::try_from(encoded).unwrap().raw, [1, 2]);
748 assert_eq!(LifetimeFixed::try_from(&encoded).unwrap().raw, [1, 2]);
749 assert_eq!(
750 LifetimeFixed::try_from([1u8, 2].as_slice()).unwrap().raw,
751 [1, 2]
752 );
753 }
754}