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>;
217
218 #[doc(hidden)]
230 #[inline]
231 fn read_vec(buf: &mut impl Buf, len: usize, cfg: &Self::Cfg) -> Result<Vec<Self>, Error> {
232 let mut values = Vec::with_capacity(len.min(buf.remaining()));
233 for _ in 0..len {
234 values.push(Self::read_cfg(buf, cfg)?);
235 }
236 Ok(values)
237 }
238
239 #[doc(hidden)]
249 #[inline]
250 fn read_array<const N: usize>(buf: &mut impl Buf, cfg: &Self::Cfg) -> Result<[Self; N], Error> {
251 Ok(Self::read_vec(buf, N, cfg)?
252 .try_into()
253 .unwrap_or_else(|_| unreachable!("array length should match capacity")))
254 }
255}
256
257pub trait Encode: Write + EncodeSize {
262 fn encode(&self) -> Bytes {
273 self.encode_mut().freeze()
274 }
275
276 fn encode_mut(&self) -> BytesMut {
287 let len = self.encode_size();
288 let mut buffer = BytesMut::with_capacity(len);
289 self.write(&mut buffer);
290 assert_eq!(buffer.len(), len, "write() did not write expected bytes");
291 buffer
292 }
293}
294
295impl<T: Write + EncodeSize> Encode for T {}
297
298pub trait EncodeShared: Encode + Send + Sync {}
302
303impl<T: Encode + Send + Sync> EncodeShared for T {}
305
306pub trait Decode: Read {
310 fn decode_cfg(mut buf: impl Buf, cfg: &Self::Cfg) -> Result<Self, Error> {
315 let result = Self::read_cfg(&mut buf, cfg)?;
316
317 let remaining = buf.remaining();
319 if remaining > 0 {
320 return Err(Error::ExtraData(remaining));
321 }
322
323 Ok(result)
324 }
325}
326
327impl<T: Read> Decode for T {}
329
330pub trait Codec: Encode + Decode {}
334
335impl<T: Encode + Decode> Codec for T {}
337
338pub trait EncodeFixed: Write + FixedSize {
340 fn encode_fixed<const N: usize>(&self) -> [u8; N] {
347 assert_eq!(
350 N,
351 Self::SIZE,
352 "Can't encode {} bytes into {} bytes",
353 Self::SIZE,
354 N
355 );
356
357 let mut array = [0u8; N];
358 let mut buf = &mut array[..];
359 self.write(&mut buf);
360 assert_eq!(buf.len(), 0);
361 array
362 }
363}
364
365impl<T: Write + FixedSize> EncodeFixed for T {}
367
368pub trait DecodeFixed: Read<Cfg = ()> + FixedSize {
370 fn decode_fixed<const N: usize>(bytes: [u8; N]) -> Result<Self, Error> {
376 assert_eq!(
377 N,
378 Self::SIZE,
379 "Can't decode {} bytes into {} bytes",
380 N,
381 Self::SIZE
382 );
383
384 Self::decode_cfg(bytes.as_ref(), &())
385 }
386}
387
388impl<T: Read<Cfg = ()> + FixedSize> DecodeFixed for T {}
390
391pub trait CodecFixed: Codec + FixedSize {}
395
396impl<T: Codec + FixedSize> CodecFixed for T {}
398
399pub trait CodecShared: Codec + Send + Sync {}
403
404impl<T: Codec + Send + Sync> CodecShared for T {}
406
407pub trait CodecFixedShared: CodecFixed<Cfg = ()> + Send + Sync {}
412
413impl<T: CodecFixed<Cfg = ()> + Send + Sync> CodecFixedShared for T {}
415
416pub trait BufsMut: BufMut {
418 fn push(&mut self, bytes: impl Into<Bytes>);
421}
422
423#[cfg(test)]
424mod tests {
425 use super::*;
426 use crate::{
427 Error, FixedArray,
428 extensions::{DecodeExt, ReadExt},
429 };
430 use bytes::Bytes;
431 use core::marker::PhantomData;
432
433 #[test]
434 fn test_insufficient_buffer() {
435 let mut reader = Bytes::from_static(&[0x01, 0x02]);
436 assert!(matches!(u32::read(&mut reader), Err(Error::EndOfBuffer)));
437 }
438
439 #[test]
440 fn test_extra_data() {
441 let encoded = Bytes::from_static(&[0x01, 0x02]);
442 assert!(matches!(u8::decode(encoded), Err(Error::ExtraData(1))));
443 }
444
445 #[test]
446 fn test_encode_fixed() {
447 let value = 42u32;
448 let encoded: [u8; 4] = value.encode_fixed();
449 let decoded = <u32>::decode(&encoded[..]).unwrap();
450 assert_eq!(value, decoded);
451 }
452
453 #[test]
454 fn test_arc_encode() {
455 let value = Arc::new(vec![1u8, 2, 3]);
456
457 assert_eq!(value.encode(), value.as_ref().encode());
458 assert_eq!(value.encode_size(), value.as_ref().encode_size());
459 }
460
461 #[test]
462 #[should_panic(expected = "Can't encode 4 bytes into 5 bytes")]
463 fn test_encode_fixed_panic() {
464 let _: [u8; 5] = 42u32.encode_fixed();
465 }
466
467 #[derive(Debug, Eq, PartialEq, FixedArray)]
468 struct FixedBytes([u8; 2]);
469
470 impl Write for FixedBytes {
471 fn write(&self, buf: &mut impl BufMut) {
472 self.0.write(buf);
473 }
474 }
475
476 impl Read for FixedBytes {
477 type Cfg = ();
478
479 fn read_cfg(buf: &mut impl Buf, _: &()) -> Result<Self, Error> {
480 Ok(Self(<[u8; Self::SIZE]>::read(buf)?))
481 }
482 }
483
484 impl FixedSize for FixedBytes {
485 const SIZE: usize = 2;
486 }
487
488 #[test]
489 fn test_fixed_array() {
490 let value = FixedBytes([1, 2]);
491 let encoded: [u8; FixedBytes::SIZE] = (&value).into();
492 assert_eq!(encoded, [1, 2]);
493 assert_eq!(<[u8; FixedBytes::SIZE]>::from(value), encoded);
494 assert_eq!(FixedBytes::try_from(encoded).unwrap(), FixedBytes([1, 2]));
495 assert_eq!(FixedBytes::try_from(&encoded).unwrap(), FixedBytes([1, 2]));
496 assert_eq!(
497 FixedBytes::try_from([1u8, 2].as_slice()).unwrap(),
498 FixedBytes([1, 2])
499 );
500 assert!(matches!(
501 FixedBytes::try_from([1u8].as_slice()),
502 Err(Error::EndOfBuffer)
503 ));
504 assert!(matches!(
505 FixedBytes::try_from([1u8, 2, 3].as_slice()),
506 Err(Error::ExtraData(1))
507 ));
508 }
509
510 #[test]
511 fn test_decode_fixed() {
512 assert_eq!(
513 FixedBytes::decode_fixed([1, 2]).unwrap(),
514 FixedBytes([1, 2])
515 );
516 }
517
518 #[test]
519 #[should_panic(expected = "Can't decode 3 bytes into 2 bytes")]
520 fn test_decode_fixed_panic() {
521 let _ = FixedBytes::decode_fixed([1, 2, 3]);
522 }
523
524 #[derive(Debug, Eq, PartialEq, FixedArray)]
525 #[fixed_array(infallible)]
526 struct InfallibleFixedBytes([u8; 2]);
527
528 impl Write for InfallibleFixedBytes {
529 fn write(&self, buf: &mut impl BufMut) {
530 self.0.write(buf);
531 }
532 }
533
534 impl Read for InfallibleFixedBytes {
535 type Cfg = ();
536
537 fn read_cfg(buf: &mut impl Buf, _: &()) -> Result<Self, Error> {
538 Ok(Self(<[u8; Self::SIZE]>::read(buf)?))
539 }
540 }
541
542 impl FixedSize for InfallibleFixedBytes {
543 const SIZE: usize = 2;
544 }
545
546 #[test]
547 fn test_fixed_array_infallible() {
548 let value = InfallibleFixedBytes([1, 2]);
549 let encoded: [u8; InfallibleFixedBytes::SIZE] = (&value).into();
550 assert_eq!(encoded, [1, 2]);
551 assert_eq!(<[u8; InfallibleFixedBytes::SIZE]>::from(value), encoded);
552 assert_eq!(
553 InfallibleFixedBytes::from(encoded),
554 InfallibleFixedBytes([1, 2])
555 );
556 assert_eq!(
557 InfallibleFixedBytes::from(&encoded),
558 InfallibleFixedBytes([1, 2])
559 );
560 assert_eq!(
561 InfallibleFixedBytes::try_from([1u8, 2].as_slice()).unwrap(),
562 InfallibleFixedBytes([1, 2])
563 );
564 assert!(matches!(
565 InfallibleFixedBytes::try_from([1u8, 2, 3].as_slice()),
566 Err(Error::ExtraData(1))
567 ));
568 }
569
570 #[derive(Debug, Eq, PartialEq, FixedArray)]
571 #[fixed_array(bytes([u8; N]))]
572 struct GenericFixed<const N: usize>([u8; N]);
573
574 impl<const N: usize> Write for GenericFixed<N> {
575 fn write(&self, buf: &mut impl BufMut) {
576 self.0.write(buf);
577 }
578 }
579
580 impl<const N: usize> Read for GenericFixed<N> {
581 type Cfg = ();
582
583 fn read_cfg(buf: &mut impl Buf, _: &()) -> Result<Self, Error> {
584 Ok(Self(<[u8; N]>::read(buf)?))
585 }
586 }
587
588 impl<const N: usize> FixedSize for GenericFixed<N> {
589 const SIZE: usize = N;
590 }
591
592 #[test]
593 fn test_fixed_array_generic() {
594 let value = GenericFixed::<3>([1, 2, 3]);
595 let encoded: [u8; 3] = (&value).into();
596 assert_eq!(encoded, [1, 2, 3]);
597 assert_eq!(<[u8; 3]>::from(value), encoded);
598 assert_eq!(
599 GenericFixed::<3>::try_from(encoded).unwrap(),
600 GenericFixed([1, 2, 3])
601 );
602 assert_eq!(
603 GenericFixed::<3>::try_from(&encoded).unwrap(),
604 GenericFixed([1, 2, 3])
605 );
606 assert_eq!(
607 GenericFixed::<3>::try_from([1u8, 2, 3].as_slice()).unwrap(),
608 GenericFixed([1, 2, 3])
609 );
610 }
611
612 #[derive(Debug, Eq, PartialEq, FixedArray)]
613 #[fixed_array(infallible, bytes([u8; N]))]
614 struct GenericInfallible<const N: usize>([u8; N]);
615
616 impl<const N: usize> Write for GenericInfallible<N> {
617 fn write(&self, buf: &mut impl BufMut) {
618 self.0.write(buf);
619 }
620 }
621
622 impl<const N: usize> Read for GenericInfallible<N> {
623 type Cfg = ();
624
625 fn read_cfg(buf: &mut impl Buf, _: &()) -> Result<Self, Error> {
626 Ok(Self(<[u8; N]>::read(buf)?))
627 }
628 }
629
630 impl<const N: usize> FixedSize for GenericInfallible<N> {
631 const SIZE: usize = N;
632 }
633
634 #[test]
635 fn test_fixed_array_generic_infallible() {
636 let value = GenericInfallible::<3>([1, 2, 3]);
637 let encoded: [u8; 3] = (&value).into();
638 assert_eq!(encoded, [1, 2, 3]);
639 assert_eq!(<[u8; 3]>::from(value), encoded);
640 assert_eq!(
641 GenericInfallible::<3>::from(encoded),
642 GenericInfallible([1, 2, 3])
643 );
644 assert_eq!(
645 GenericInfallible::<3>::from(&encoded),
646 GenericInfallible([1, 2, 3])
647 );
648 assert_eq!(
649 GenericInfallible::<3>::try_from([1u8, 2, 3].as_slice()).unwrap(),
650 GenericInfallible([1, 2, 3])
651 );
652 }
653
654 trait FixedArrayBound {}
655
656 #[derive(Debug, Eq, PartialEq)]
657 struct Bounded;
658
659 impl FixedArrayBound for Bounded {}
660
661 #[derive(Debug, Eq, PartialEq, FixedArray)]
662 #[fixed_array(bytes([u8; 2]))]
663 struct BoundedGeneric<T> {
664 marker: PhantomData<T>,
665 raw: [u8; 2],
666 }
667
668 impl<T: FixedArrayBound> Write for BoundedGeneric<T> {
669 fn write(&self, buf: &mut impl BufMut) {
670 self.raw.write(buf);
671 }
672 }
673
674 impl<T: FixedArrayBound> Read for BoundedGeneric<T> {
675 type Cfg = ();
676
677 fn read_cfg(buf: &mut impl Buf, _: &()) -> Result<Self, Error> {
678 Ok(Self {
679 marker: PhantomData,
680 raw: <[u8; 2]>::read(buf)?,
681 })
682 }
683 }
684
685 impl<T: FixedArrayBound> FixedSize for BoundedGeneric<T> {
686 const SIZE: usize = 2;
687 }
688
689 #[test]
690 fn test_fixed_array_bounded_generic() {
691 let value = BoundedGeneric::<Bounded> {
692 marker: PhantomData,
693 raw: [1, 2],
694 };
695 let encoded: [u8; 2] = (&value).into();
696 assert_eq!(encoded, [1, 2]);
697 assert_eq!(<[u8; 2]>::from(value).as_ref(), &[1, 2]);
698 assert_eq!(
699 BoundedGeneric::<Bounded>::try_from(encoded).unwrap().raw,
700 [1, 2]
701 );
702 assert_eq!(
703 BoundedGeneric::<Bounded>::try_from(&encoded).unwrap().raw,
704 [1, 2]
705 );
706 assert_eq!(
707 BoundedGeneric::<Bounded>::try_from([1u8, 2].as_slice())
708 .unwrap()
709 .raw,
710 [1, 2]
711 );
712 }
713
714 #[derive(Debug, Eq, PartialEq, FixedArray)]
715 #[fixed_array(bytes([u8; 2]))]
716 struct LifetimeFixed<'a> {
717 marker: PhantomData<&'a ()>,
718 raw: [u8; 2],
719 }
720
721 impl Write for LifetimeFixed<'_> {
722 fn write(&self, buf: &mut impl BufMut) {
723 self.raw.write(buf);
724 }
725 }
726
727 impl Read for LifetimeFixed<'_> {
728 type Cfg = ();
729
730 fn read_cfg(buf: &mut impl Buf, _: &()) -> Result<Self, Error> {
731 Ok(Self {
732 marker: PhantomData,
733 raw: <[u8; 2]>::read(buf)?,
734 })
735 }
736 }
737
738 impl FixedSize for LifetimeFixed<'_> {
739 const SIZE: usize = 2;
740 }
741
742 #[test]
743 fn test_fixed_array_lifetime() {
744 let value = LifetimeFixed {
745 marker: PhantomData,
746 raw: [1, 2],
747 };
748 let encoded: [u8; LifetimeFixed::SIZE] = (&value).into();
749 assert_eq!(encoded, [1, 2]);
750 assert_eq!(<[u8; LifetimeFixed::SIZE]>::from(value).as_ref(), &[1, 2]);
751 assert_eq!(LifetimeFixed::try_from(encoded).unwrap().raw, [1, 2]);
752 assert_eq!(LifetimeFixed::try_from(&encoded).unwrap().raw, [1, 2]);
753 assert_eq!(
754 LifetimeFixed::try_from([1u8, 2].as_slice()).unwrap().raw,
755 [1, 2]
756 );
757 }
758}