1use {
48 crate::{
49 config::{self, ConfigCore, DefaultConfig},
50 error::{ReadResult, WriteResult},
51 io::*,
52 len::SeqLen,
53 },
54 core::{borrow::Borrow, mem::MaybeUninit},
55};
56
57pub mod adapter;
58mod compile_fail;
59pub mod containers;
60pub mod context;
61mod external;
62mod impls;
63pub mod int_encoding;
64pub mod tag_encoding;
65
66#[derive(Debug, Clone, Copy, PartialEq, Eq)]
70pub enum TypeMeta {
71 Static {
82 size: usize,
84 zero_copy: bool,
91 },
92 Dynamic,
94}
95
96impl TypeMeta {
97 #[inline(always)]
98 pub(crate) const fn size_assert_zero_copy(self) -> usize {
99 match self {
100 TypeMeta::Static {
101 size,
102 zero_copy: true,
103 } => size,
104 _ => panic!("Type is not zero-copy"),
105 }
106 }
107
108 #[cfg(all(test, feature = "std", feature = "derive"))]
109 pub(crate) const fn size_assert_static(self) -> usize {
110 match self {
111 TypeMeta::Static { size, zero_copy: _ } => size,
112 _ => panic!("Type is not static"),
113 }
114 }
115
116 pub const fn keep_zero_copy(self, keep_zero_copy: bool) -> Self {
127 match self {
128 Self::Static { size, zero_copy } => TypeMeta::Static {
129 size,
130 zero_copy: zero_copy && keep_zero_copy,
131 },
132 Self::Dynamic => Self::Dynamic,
133 }
134 }
135
136 #[expect(clippy::arithmetic_side_effects)]
185 pub const fn join_types<const N: usize>(types: [Self; N]) -> Self {
186 let mut acc_size = 0;
187 let mut all_zero_copy = true;
188 let mut i = 0;
189 while i < N {
190 match types[i] {
191 Self::Dynamic => return Self::Dynamic,
192 Self::Static { size, zero_copy } => {
193 acc_size += size;
194 all_zero_copy &= zero_copy;
195 }
196 }
197 i += 1;
198 }
199 Self::Static {
200 size: acc_size,
201 zero_copy: all_zero_copy,
202 }
203 }
204}
205
206pub unsafe trait SchemaWrite<C: ConfigCore> {
213 type Src: ?Sized;
214
215 const TYPE_META: TypeMeta = TypeMeta::Dynamic;
228
229 #[cfg(test)]
230 #[allow(unused_variables)]
231 fn type_meta(config: C) -> TypeMeta {
232 Self::TYPE_META
233 }
234
235 fn size_of(src: &Self::Src) -> WriteResult<usize>;
242
243 fn write(writer: impl Writer, src: &Self::Src) -> WriteResult<()>;
245}
246
247pub unsafe trait SchemaRead<'de, C: ConfigCore> {
254 type Dst;
255
256 const TYPE_META: TypeMeta = TypeMeta::Dynamic;
268
269 #[cfg(test)]
270 #[allow(unused_variables)]
271 fn type_meta(config: C) -> TypeMeta {
272 Self::TYPE_META
273 }
274
275 fn read(reader: impl Reader<'de>, dst: &mut MaybeUninit<Self::Dst>) -> ReadResult<()>;
285
286 #[inline(always)]
288 fn get(reader: impl Reader<'de>) -> ReadResult<Self::Dst> {
289 let mut value = MaybeUninit::uninit();
290 Self::read(reader, &mut value)?;
291 Ok(unsafe { value.assume_init() })
293 }
294}
295
296pub unsafe trait SchemaReadContext<'de, C: ConfigCore, Ctx> {
303 type Dst;
304
305 const TYPE_META: TypeMeta = TypeMeta::Dynamic;
317
318 fn read_with_context(
326 ctx: Ctx,
327 reader: impl Reader<'de>,
328 dst: &mut MaybeUninit<Self::Dst>,
329 ) -> ReadResult<()>;
330
331 #[inline(always)]
333 fn get_with_context(ctx: Ctx, reader: impl Reader<'de>) -> ReadResult<Self::Dst> {
334 let mut value = MaybeUninit::uninit();
335 Self::read_with_context(ctx, reader, &mut value)?;
336 Ok(unsafe { value.assume_init() })
338 }
339}
340
341pub unsafe trait ZeroCopy: config::ZeroCopy<DefaultConfig> {
352 #[inline(always)]
376 fn from_bytes<'de>(bytes: &'de [u8]) -> ReadResult<&'de Self>
377 where
378 Self: SchemaRead<'de, DefaultConfig, Dst = Self> + Sized,
379 {
380 <&Self as SchemaRead<'de, DefaultConfig>>::get(bytes)
381 }
382
383 #[inline(always)]
410 fn from_bytes_mut<'de>(bytes: &'de mut [u8]) -> ReadResult<&'de mut Self>
411 where
412 Self: SchemaRead<'de, DefaultConfig, Dst = Self> + Sized,
413 {
414 <&mut Self as SchemaRead<'de, DefaultConfig>>::get(bytes)
415 }
416}
417
418unsafe impl<T> ZeroCopy for T where T: config::ZeroCopy<DefaultConfig> {}
419
420pub trait SchemaReadOwned<C: ConfigCore>: for<'de> SchemaRead<'de, C> {}
422impl<T, C: ConfigCore> SchemaReadOwned<C> for T where T: for<'de> SchemaRead<'de, C> {}
423
424#[inline(always)]
425#[allow(clippy::arithmetic_side_effects)]
426fn size_of_elem_iter<T, Len, C>(
427 value: impl ExactSizeIterator<Item: Borrow<T::Src>>,
428) -> WriteResult<usize>
429where
430 C: ConfigCore,
431 Len: SeqLen<C>,
432 T: SchemaWrite<C>,
433{
434 if let TypeMeta::Static { size, .. } = T::TYPE_META {
435 return Ok(Len::write_bytes_needed(value.len())? + size * value.len());
436 }
437 Ok(Len::write_bytes_needed(value.len())?
439 + (value
440 .map(|x| T::size_of(x.borrow()))
441 .try_fold(0usize, |acc, x| x.map(|x| acc + x))?))
442}
443
444#[inline(always)]
445#[allow(clippy::arithmetic_side_effects)]
446fn size_of_elem_slice<T, Len, C>(value: &[T::Src]) -> WriteResult<usize>
448where
449 C: ConfigCore,
450 Len: SeqLen<C>,
451 T: SchemaWrite<C>,
452 T::Src: Sized,
453{
454 size_of_elem_iter::<T, Len, C>(value.iter())
455}
456
457#[inline(always)]
458fn write_elem_iter<T, Len, C>(
459 mut writer: impl Writer,
460 mut src: impl ExactSizeIterator<Item: Borrow<T::Src>>,
461) -> WriteResult<()>
462where
463 C: ConfigCore,
464 Len: SeqLen<C>,
465 T: SchemaWrite<C>,
466{
467 #[cold]
468 fn short_iter() -> crate::WriteError {
469 crate::WriteError::Custom(
470 "ExactSizeIterator yielded fewer elements than its reported len()",
471 )
472 }
473
474 let len = src.len();
479 macro_rules! write_elems {
480 ($w:expr) => {{
481 Len::write($w.by_ref(), len)?;
482 for _ in 0..len {
483 let item = src.next().ok_or_else(short_iter)?;
484 T::write($w.by_ref(), item.borrow())?;
485 }
486 }};
487 }
488
489 if let TypeMeta::Static { size, .. } = T::TYPE_META {
490 #[allow(clippy::arithmetic_side_effects)]
491 let needed = Len::write_bytes_needed(len)? + size * len;
492 let mut writer = unsafe { writer.as_trusted_for(needed) }?;
497 write_elems!(writer);
498 writer.finish()?;
499 return Ok(());
500 }
501
502 write_elems!(writer);
503 Ok(())
504}
505
506#[inline(always)]
507#[cfg(feature = "alloc")]
508fn write_elem_iter_prealloc_check<T, Len, C>(
509 writer: impl Writer,
510 src: impl ExactSizeIterator<Item: Borrow<T::Src>>,
511) -> WriteResult<()>
512where
513 C: ConfigCore,
514 Len: SeqLen<C>,
515 T: SchemaWrite<C>,
516 T::Src: Sized,
517{
518 Len::prealloc_check::<T::Src>(src.len())?;
519 write_elem_iter::<T, Len, C>(writer, src)
520}
521
522#[inline(always)]
523#[allow(clippy::arithmetic_side_effects)]
524fn write_elem_slice<T, Len, C>(mut writer: impl Writer, src: &[T::Src]) -> WriteResult<()>
527where
528 C: ConfigCore,
529 Len: SeqLen<C>,
530 T: SchemaWrite<C>,
531 T::Src: Sized,
532{
533 if let TypeMeta::Static {
534 size,
535 zero_copy: true,
536 } = T::TYPE_META
537 {
538 let needed = Len::write_bytes_needed(src.len())? + src.len() * size;
539 let mut writer = unsafe { writer.as_trusted_for(needed) }?;
543 Len::write(writer.by_ref(), src.len())?;
544 unsafe { writer.write_slice_t(src)? };
546 writer.finish()?;
547 return Ok(());
548 }
549 write_elem_iter::<T, Len, C>(writer, src.iter())
550}
551
552#[inline(always)]
553#[cfg(feature = "alloc")]
554fn write_elem_slice_prealloc_check<T, Len, C>(
555 writer: impl Writer,
556 src: &[T::Src],
557) -> WriteResult<()>
558where
559 C: ConfigCore,
560 Len: SeqLen<C>,
561 T: SchemaWrite<C>,
562 T::Src: Sized,
563{
564 Len::prealloc_check::<T::Src>(src.len())?;
565 write_elem_slice::<T, Len, C>(writer, src)
566}
567
568#[cfg(all(test, feature = "std", feature = "derive"))]
569mod tests {
570 #![allow(clippy::arithmetic_side_effects)]
571
572 use {
573 crate::{
574 Deserialize, ReadError, ReadResult, SchemaRead, SchemaReadContext, SchemaWrite,
575 Serialize, TypeMeta, UninitBuilder, WriteError, WriteResult, ZeroCopy,
576 config::{self, Config, ConfigCore, Configuration, DefaultConfig},
577 containers, context, deserialize, deserialize_exact, deserialize_mut,
578 error::{self, invalid_tag_encoding},
579 io::{Reader, Writer, test_util::NoBorrowReader},
580 len::{BincodeLen, FixIntLen, UseIntLen},
581 pod_wrapper,
582 proptest_config::proptest_cfg,
583 serialize,
584 },
585 bincode::Options,
586 core::{marker::PhantomData, ptr},
587 proptest::prelude::*,
588 std::{
589 alloc::Layout,
590 borrow::Cow,
591 cell::{Cell, RefCell},
592 collections::{BinaryHeap, HashMap, HashSet, VecDeque},
593 hash::{BuildHasher, Hasher},
594 mem::MaybeUninit,
595 net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6},
596 num::{
597 NonZeroI8, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI128, NonZeroIsize,
598 NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128, NonZeroUsize,
599 },
600 ops::{Bound, Deref, DerefMut, Range, RangeInclusive},
601 rc::Rc,
602 result::Result,
603 sync::{Arc, Mutex, RwLock},
604 time::{Duration, SystemTime, UNIX_EPOCH},
605 },
606 };
607
608 #[cfg(target_endian = "little")]
609 #[derive(
610 serde::Serialize,
611 serde::Deserialize,
612 Debug,
613 PartialEq,
614 Eq,
615 Ord,
616 PartialOrd,
617 SchemaWrite,
618 SchemaRead,
619 proptest_derive::Arbitrary,
620 Hash,
621 Clone,
622 Copy,
623 )]
624 #[wincode(internal)]
625 #[repr(C)]
626 struct StructZeroCopy {
627 a: u128,
628 b: i128,
629 c: u64,
630 d: i64,
631 e: u32,
632 f: i32,
633 ar1: [u8; 8],
634 g: u16,
635 h: i16,
636 ar2: [u8; 12],
637 i: u8,
638 j: i8,
639 ar3: [u8; 14],
640 }
641
642 #[cfg(not(target_endian = "little"))]
643 #[derive(
644 serde::Serialize,
645 serde::Deserialize,
646 Debug,
647 PartialEq,
648 Eq,
649 Ord,
650 PartialOrd,
651 SchemaWrite,
652 SchemaRead,
653 proptest_derive::Arbitrary,
654 Hash,
655 Clone,
656 Copy,
657 )]
658 #[wincode(internal)]
659 #[repr(C)]
660 struct StructZeroCopy {
661 byte: u8,
662 ar: [u8; 32],
663 }
664
665 #[derive(
666 serde::Serialize,
667 serde::Deserialize,
668 Debug,
669 PartialEq,
670 Eq,
671 Ord,
672 PartialOrd,
673 SchemaWrite,
674 SchemaRead,
675 proptest_derive::Arbitrary,
676 Hash,
677 )]
678 #[wincode(internal)]
679 struct StructStatic {
680 a: u64,
681 b: bool,
682 e: [u8; 32],
683 }
684
685 #[derive(
686 serde::Serialize,
687 serde::Deserialize,
688 Debug,
689 PartialEq,
690 Eq,
691 Ord,
692 PartialOrd,
693 SchemaWrite,
694 SchemaRead,
695 proptest_derive::Arbitrary,
696 Hash,
697 )]
698 #[wincode(internal)]
699 struct StructNonStatic {
700 a: u64,
701 b: bool,
702 e: String,
703 }
704
705 #[test]
706 fn struct_zero_copy_derive_size() {
707 #[cfg(target_endian = "little")]
708 let size = size_of::<u128>()
709 + size_of::<i128>()
710 + size_of::<u64>()
711 + size_of::<i64>()
712 + size_of::<u32>()
713 + size_of::<i32>()
714 + size_of::<[u8; 8]>()
715 + size_of::<u16>()
716 + size_of::<i16>()
717 + size_of::<[u8; 12]>()
718 + size_of::<u8>()
719 + size_of::<i8>()
720 + size_of::<[u8; 14]>();
721 #[cfg(not(target_endian = "little"))]
722 let size = size_of::<u8>() + size_of::<[u8; 32]>();
723 let expected = TypeMeta::Static {
724 size,
725 zero_copy: true,
726 };
727 assert_eq!(
728 <StructZeroCopy as SchemaWrite<DefaultConfig>>::TYPE_META,
729 expected
730 );
731 assert_eq!(
732 <StructZeroCopy as SchemaRead<'_, DefaultConfig>>::TYPE_META,
733 expected
734 );
735 }
736
737 #[test]
738 fn struct_zero_copy_transparent_derive_size() {
739 #[derive(SchemaWrite, SchemaRead)]
740 #[wincode(internal)]
741 #[repr(transparent)]
742 struct Address([u8; 32]);
743
744 let expected = TypeMeta::Static {
745 size: size_of::<[u8; 32]>(),
746 zero_copy: true,
747 };
748 assert_eq!(<Address as SchemaWrite<DefaultConfig>>::TYPE_META, expected);
749 assert_eq!(
750 <Address as SchemaRead<'_, DefaultConfig>>::TYPE_META,
751 expected
752 );
753 }
754
755 #[test]
756 fn struct_static_derive_size() {
757 let expected = TypeMeta::Static {
758 size: size_of::<u64>() + size_of::<bool>() + size_of::<[u8; 32]>(),
759 zero_copy: false,
760 };
761 assert_eq!(
762 <StructStatic as SchemaWrite<DefaultConfig>>::TYPE_META,
763 expected
764 );
765 assert_eq!(
766 <StructStatic as SchemaRead<'_, DefaultConfig>>::TYPE_META,
767 expected
768 );
769 }
770
771 #[test]
772 fn struct_non_static_derive_size() {
773 let expected = TypeMeta::Dynamic;
774 assert_eq!(
775 <StructNonStatic as SchemaWrite<DefaultConfig>>::TYPE_META,
776 expected
777 );
778 assert_eq!(
779 <StructNonStatic as SchemaRead<'_, DefaultConfig>>::TYPE_META,
780 expected
781 );
782 }
783
784 #[test]
785 fn test_cell_roundtrip() {
786 let value = Cell::new(0x0123_4567_89ab_cdef_u64);
787 let serialized = serialize(&value).unwrap();
788 let deserialized: Cell<u64> = deserialize(&serialized).unwrap();
789
790 assert_eq!(value.get(), deserialized.get());
791 assert_eq!(
792 <Cell<u64> as SchemaWrite<DefaultConfig>>::TYPE_META,
793 TypeMeta::Static {
794 size: size_of::<u64>(),
795 zero_copy: false
796 }
797 );
798 assert_eq!(
799 <Cell<u64> as SchemaRead<'_, DefaultConfig>>::TYPE_META,
800 TypeMeta::Static {
801 size: size_of::<u64>(),
802 zero_copy: true
803 }
804 );
805 }
806
807 #[test]
808 fn test_refcell_roundtrip() {
809 let value = RefCell::new(String::from("hello from a refcell"));
810 let serialized = serialize(&value).unwrap();
811 let deserialized: RefCell<String> = deserialize(&serialized).unwrap();
812
813 assert_eq!(&*value.borrow(), &*deserialized.borrow());
814 assert_eq!(
815 <RefCell<String> as SchemaWrite<DefaultConfig>>::TYPE_META,
816 TypeMeta::Dynamic
817 );
818 assert_eq!(
819 <RefCell<String> as SchemaRead<'_, DefaultConfig>>::TYPE_META,
820 TypeMeta::Dynamic
821 );
822 }
823
824 #[test]
825 fn test_refcell_write_errors_while_mutably_borrowed() {
826 let value = RefCell::new(123_u32);
827 let _borrow = value.borrow_mut();
828
829 assert!(<RefCell<u32> as SchemaWrite<DefaultConfig>>::size_of(&value).is_err());
830
831 let mut bytes = Vec::new();
832 assert!(<RefCell<u32> as SchemaWrite<DefaultConfig>>::write(&mut bytes, &value).is_err());
833 assert!(serialize(&value).is_err());
834 }
835
836 #[test]
837 fn test_refcell_unsized_slice_write() {
838 let value = RefCell::new([1_u8, 2, 3, 4]);
839 let value: &RefCell<[u8]> = &value;
840
841 let serialized = <RefCell<[u8]> as Serialize>::serialize(value).unwrap();
842 let expected = serialize(&[1_u8, 2, 3, 4][..]).unwrap();
843
844 assert_eq!(serialized, expected);
845 }
846
847 thread_local! {
848 static TL_DROP_COUNT: Cell<isize> = const { Cell::new(0) };
850 }
851
852 fn get_tl_drop_count() -> isize {
853 TL_DROP_COUNT.with(|cell| cell.get())
854 }
855
856 fn tl_drop_count_inc() {
857 TL_DROP_COUNT.with(|cell| cell.set(cell.get() + 1));
858 }
859
860 fn tl_drop_count_dec() {
861 TL_DROP_COUNT.with(|cell| cell.set(cell.get() - 1));
862 }
863
864 fn tl_drop_count_reset() {
865 TL_DROP_COUNT.with(|cell| cell.set(0));
866 }
867
868 #[must_use]
869 #[derive(Debug)]
870 struct TLDropGuard;
872
873 impl TLDropGuard {
874 fn new() -> Self {
875 assert_eq!(
876 get_tl_drop_count(),
877 0,
878 "TL counter drifted from zero -- another test may have leaked"
879 );
880 Self
881 }
882 }
883
884 impl Drop for TLDropGuard {
885 #[track_caller]
886 fn drop(&mut self) {
887 let v = get_tl_drop_count();
888 if !std::thread::panicking() {
889 assert_eq!(
890 v, 0,
891 "TL counter drifted from zero -- this test might have leaked"
892 );
893 }
894 tl_drop_count_reset();
895 }
896 }
897
898 #[derive(Debug, PartialEq, Eq)]
899 struct DropCounted;
901
902 impl Arbitrary for DropCounted {
903 type Parameters = ();
904 type Strategy = Just<Self>;
905 fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
906 Just(Self::new())
907 }
908 }
909
910 impl DropCounted {
911 const TAG_BYTE: u8 = 0;
912
913 fn new() -> Self {
914 tl_drop_count_inc();
915 Self
916 }
917 }
918
919 impl Clone for DropCounted {
920 fn clone(&self) -> Self {
921 tl_drop_count_inc();
922 Self
923 }
924 }
925
926 impl Drop for DropCounted {
927 fn drop(&mut self) {
928 tl_drop_count_dec();
929 }
930 }
931
932 unsafe impl<C: Config> SchemaWrite<C> for DropCounted {
933 type Src = Self;
934
935 const TYPE_META: TypeMeta = TypeMeta::Static {
936 size: 1,
937 zero_copy: false,
938 };
939
940 fn size_of(_src: &Self::Src) -> WriteResult<usize> {
941 Ok(1)
942 }
943 fn write(writer: impl Writer, _src: &Self::Src) -> WriteResult<()> {
944 <u8 as SchemaWrite<C>>::write(writer, &Self::TAG_BYTE)?;
945 Ok(())
946 }
947 }
948
949 unsafe impl<'de, C: Config> SchemaRead<'de, C> for DropCounted {
950 type Dst = Self;
951
952 const TYPE_META: TypeMeta = TypeMeta::Static {
953 size: 1,
954 zero_copy: false,
955 };
956
957 fn read(mut reader: impl Reader<'de>, dst: &mut MaybeUninit<Self::Dst>) -> ReadResult<()> {
958 reader.take_byte()?;
959 dst.write(DropCounted::new());
961 Ok(())
962 }
963 }
964
965 #[derive(Debug, Clone, Copy, PartialEq, Eq, proptest_derive::Arbitrary)]
967 struct ErrorsOnRead;
968
969 impl ErrorsOnRead {
970 const TAG_BYTE: u8 = 1;
971 }
972
973 unsafe impl<C: Config> SchemaWrite<C> for ErrorsOnRead {
974 type Src = Self;
975
976 const TYPE_META: TypeMeta = TypeMeta::Static {
977 size: 1,
978 zero_copy: false,
979 };
980
981 fn size_of(_src: &Self::Src) -> WriteResult<usize> {
982 Ok(1)
983 }
984
985 fn write(writer: impl Writer, _src: &Self::Src) -> WriteResult<()> {
986 <u8 as SchemaWrite<C>>::write(writer, &Self::TAG_BYTE)
987 }
988 }
989
990 unsafe impl<'de, C: Config> SchemaRead<'de, C> for ErrorsOnRead {
991 type Dst = Self;
992
993 const TYPE_META: TypeMeta = TypeMeta::Static {
994 size: 1,
995 zero_copy: false,
996 };
997
998 fn read(mut reader: impl Reader<'de>, _dst: &mut MaybeUninit<Self::Dst>) -> ReadResult<()> {
999 reader.take_byte()?;
1000 Err(error::ReadError::PointerSizedReadError)
1001 }
1002 }
1003
1004 #[derive(Debug, Clone, PartialEq, Eq, proptest_derive::Arbitrary)]
1005 enum DropCountedMaybeError {
1006 DropCounted(DropCounted),
1007 ErrorsOnRead(ErrorsOnRead),
1008 }
1009
1010 unsafe impl<C: Config> SchemaWrite<C> for DropCountedMaybeError {
1011 type Src = Self;
1012
1013 const TYPE_META: TypeMeta = TypeMeta::Static {
1014 size: 1,
1015 zero_copy: false,
1016 };
1017
1018 fn size_of(src: &Self::Src) -> WriteResult<usize> {
1019 match src {
1020 DropCountedMaybeError::DropCounted(v) => {
1021 <DropCounted as SchemaWrite<C>>::size_of(v)
1022 }
1023 DropCountedMaybeError::ErrorsOnRead(v) => {
1024 <ErrorsOnRead as SchemaWrite<C>>::size_of(v)
1025 }
1026 }
1027 }
1028
1029 fn write(writer: impl Writer, src: &Self::Src) -> WriteResult<()> {
1030 match src {
1031 DropCountedMaybeError::DropCounted(v) => {
1032 <DropCounted as SchemaWrite<C>>::write(writer, v)
1033 }
1034 DropCountedMaybeError::ErrorsOnRead(v) => {
1035 <ErrorsOnRead as SchemaWrite<C>>::write(writer, v)
1036 }
1037 }
1038 }
1039 }
1040
1041 unsafe impl<'de, C: Config> SchemaRead<'de, C> for DropCountedMaybeError {
1042 type Dst = Self;
1043
1044 const TYPE_META: TypeMeta = TypeMeta::Static {
1045 size: 1,
1046 zero_copy: false,
1047 };
1048
1049 fn read(reader: impl Reader<'de>, dst: &mut MaybeUninit<Self::Dst>) -> ReadResult<()> {
1050 let byte = <u8 as SchemaRead<'de, C>>::get(reader)?;
1051 match byte {
1052 DropCounted::TAG_BYTE => {
1053 dst.write(DropCountedMaybeError::DropCounted(DropCounted::new()));
1054 Ok(())
1055 }
1056 ErrorsOnRead::TAG_BYTE => Err(error::ReadError::PointerSizedReadError),
1057 _ => Err(invalid_tag_encoding(byte as usize)),
1058 }
1059 }
1060 }
1061
1062 #[test]
1063 fn drop_count_sanity() {
1064 let _guard = TLDropGuard::new();
1065 let serialized = { serialize(&[DropCounted::new(), DropCounted::new()]).unwrap() };
1067 let _deserialized: [DropCounted; 2] = deserialize(&serialized).unwrap();
1068 assert_eq!(get_tl_drop_count(), 2);
1069 }
1070
1071 #[test]
1072 fn drop_count_maybe_error_sanity() {
1073 let _guard = TLDropGuard::new();
1074 let serialized =
1075 { serialize(&[DropCountedMaybeError::DropCounted(DropCounted::new())]).unwrap() };
1076 let _deserialized: [DropCountedMaybeError; 1] = deserialize(&serialized).unwrap();
1077 assert_eq!(get_tl_drop_count(), 1);
1078
1079 let serialized = {
1080 serialize(&[
1081 DropCountedMaybeError::DropCounted(DropCounted::new()),
1082 DropCountedMaybeError::ErrorsOnRead(ErrorsOnRead),
1083 ])
1084 .unwrap()
1085 };
1086 let _deserialized: ReadResult<[DropCountedMaybeError; 2]> = deserialize(&serialized);
1087 }
1088
1089 #[test]
1091 fn test_struct_derive_handles_partial_drop() {
1092 #[derive(SchemaWrite, SchemaRead, proptest_derive::Arbitrary, Debug, PartialEq, Eq)]
1095 #[wincode(internal)]
1096 struct CouldLeak {
1097 data: DropCountedMaybeError,
1098 data2: DropCountedMaybeError,
1099 data3: DropCountedMaybeError,
1100 }
1101
1102 let _guard = TLDropGuard::new();
1103 proptest!(proptest_cfg(), |(could_leak: CouldLeak)| {
1104 let serialized = serialize(&could_leak).unwrap();
1105 let deserialized = CouldLeak::deserialize(&serialized);
1106 if let Ok(deserialized) = deserialized {
1107 prop_assert_eq!(could_leak, deserialized);
1108 }
1109 });
1110 }
1111
1112 #[test]
1114 fn test_vec_of_references_borrows_from_input() {
1115 #[derive(
1116 SchemaWrite, SchemaRead, Debug, PartialEq, Eq, proptest_derive::Arbitrary, Clone, Copy,
1117 )]
1118 #[wincode(internal)]
1119 #[repr(transparent)]
1120 struct BigBytes([u8; 512]);
1121 proptest!(proptest_cfg(), |(vec in proptest::collection::vec(any::<BigBytes>(), 0..=8))| {
1122 let bytes = serialize(&vec).unwrap();
1124 let borrowed: Vec<&BigBytes> = deserialize(&bytes).unwrap();
1125
1126 prop_assert_eq!(borrowed.len(), vec.len());
1127 let start = bytes.as_ptr().addr();
1128 let end = start + bytes.len();
1129 for (i, r) in borrowed.iter().enumerate() {
1130 prop_assert_eq!(**r, vec[i]);
1132 let p = ptr::from_ref(*r).addr();
1134 prop_assert!(p >= start && p < end);
1135 }
1136 });
1137 }
1138
1139 #[test]
1141 fn test_boxed_slice_of_references_borrows_from_input() {
1142 #[derive(
1143 SchemaWrite, SchemaRead, Debug, PartialEq, Eq, proptest_derive::Arbitrary, Clone, Copy,
1144 )]
1145 #[wincode(internal)]
1146 #[repr(transparent)]
1147 struct BigBytes([u8; 512]);
1148 proptest!(proptest_cfg(), |(vec in proptest::collection::vec(any::<BigBytes>(), 0..=8))| {
1149 let boxed: Box<[BigBytes]> = vec.into_boxed_slice();
1150 let bytes = serialize(&boxed).unwrap();
1151 let borrowed: Box<[&BigBytes]> = deserialize(&bytes).unwrap();
1152
1153 prop_assert_eq!(borrowed.len(), boxed.len());
1154 let start = bytes.as_ptr().addr();
1155 let end = start + bytes.len();
1156 for (i, &r) in borrowed.iter().enumerate() {
1157 prop_assert_eq!(*r, boxed[i]);
1158 let p = ptr::from_ref(r).addr();
1159 prop_assert!(p >= start && p < end);
1160 }
1161 });
1162 }
1163
1164 #[test]
1166 fn test_enum_derive_handles_partial_drop() {
1167 #[derive(SchemaWrite, SchemaRead, proptest_derive::Arbitrary, Debug, PartialEq, Eq)]
1170 #[wincode(internal)]
1171 enum CouldLeak {
1172 A {
1173 a: DropCountedMaybeError,
1174 b: DropCountedMaybeError,
1175 },
1176 B(
1177 DropCountedMaybeError,
1178 DropCountedMaybeError,
1179 DropCountedMaybeError,
1180 ),
1181 C(DropCountedMaybeError),
1182 D,
1183 }
1184
1185 let _guard = TLDropGuard::new();
1186 proptest!(proptest_cfg(), |(could_leak: CouldLeak)| {
1187 let serialized = serialize(&could_leak).unwrap();
1188 let deserialized = CouldLeak::deserialize(&serialized);
1189 if let Ok(deserialized) = deserialized {
1190 prop_assert_eq!(could_leak, deserialized);
1191 }
1192 });
1193 }
1194
1195 #[test]
1196 fn test_tuple_handles_partial_drop() {
1197 let _guard = TLDropGuard::new();
1198 let serialized =
1199 { serialize(&(DropCounted::new(), DropCounted::new(), ErrorsOnRead)).unwrap() };
1200 let deserialized: ReadResult<(DropCounted, DropCounted, ErrorsOnRead)> =
1201 deserialize(&serialized);
1202 assert!(deserialized.is_err());
1203 }
1204
1205 #[test]
1206 fn test_vec_handles_partial_drop() {
1207 let _guard = TLDropGuard::new();
1208 proptest!(proptest_cfg(), |(vec in proptest::collection::vec(any::<DropCountedMaybeError>(), 0..100))| {
1209 let serialized = serialize(&vec).unwrap();
1210 let deserialized = <Vec<DropCountedMaybeError>>::deserialize(&serialized);
1211 if let Ok(deserialized) = deserialized {
1212 prop_assert_eq!(vec, deserialized);
1213 }
1214 });
1215 }
1216
1217 #[cfg(feature = "smallvec")]
1222 #[test]
1223 fn test_smallvec_handles_partial_drop() {
1224 use smallvec::SmallVec;
1225 type SmallVec4<T> = SmallVec<[T; 4]>;
1227
1228 let _guard = TLDropGuard::new();
1229 proptest!(proptest_cfg(), |(vec in proptest::collection::vec(any::<DropCountedMaybeError>(), 0..16).prop_map(SmallVec4::from_vec))| {
1230 let serialized = serialize(&vec).unwrap();
1231 let deserialized = <SmallVec4<DropCountedMaybeError>>::deserialize(&serialized);
1232 if let Ok(deserialized) = deserialized {
1233 prop_assert_eq!(vec, deserialized);
1234 }
1235 });
1236 }
1237
1238 #[test]
1239 fn test_vec_deque_handles_partial_drop() {
1240 let _guard = TLDropGuard::new();
1241 proptest!(proptest_cfg(), |(vec in proptest::collection::vec_deque(any::<DropCountedMaybeError>(), 0..100))| {
1242 let serialized = serialize(&vec).unwrap();
1243 let deserialized = <VecDeque<DropCountedMaybeError>>::deserialize(&serialized);
1244 if let Ok(deserialized) = deserialized {
1245 prop_assert_eq!(vec, deserialized);
1246 }
1247 });
1248 }
1249
1250 #[test]
1251 fn test_boxed_slice_handles_partial_drop() {
1252 let _guard = TLDropGuard::new();
1253 proptest!(proptest_cfg(), |(slice in proptest::collection::vec(any::<DropCountedMaybeError>(), 0..100).prop_map(|vec| vec.into_boxed_slice()))| {
1254 let serialized = serialize(&slice).unwrap();
1255 let deserialized = <Box<[DropCountedMaybeError]>>::deserialize(&serialized);
1256 if let Ok(deserialized) = deserialized {
1257 prop_assert_eq!(slice, deserialized);
1258 }
1259 });
1260 }
1261
1262 #[test]
1263 fn test_rc_slice_handles_partial_drop() {
1264 let _guard = TLDropGuard::new();
1265 proptest!(proptest_cfg(), |(slice in proptest::collection::vec(any::<DropCountedMaybeError>(), 0..100).prop_map(Rc::from))| {
1266 let serialized = serialize(&slice).unwrap();
1267 let deserialized = <Rc<[DropCountedMaybeError]>>::deserialize(&serialized);
1268 if let Ok(deserialized) = deserialized {
1269 prop_assert_eq!(slice, deserialized);
1270 }
1271 });
1272 }
1273
1274 #[test]
1275 fn test_arc_slice_handles_partial_drop() {
1276 let _guard = TLDropGuard::new();
1277 proptest!(proptest_cfg(), |(slice in proptest::collection::vec(any::<DropCountedMaybeError>(), 0..100).prop_map(Arc::from))| {
1278 let serialized = serialize(&slice).unwrap();
1279 let deserialized = <Arc<[DropCountedMaybeError]>>::deserialize(&serialized);
1280 if let Ok(deserialized) = deserialized {
1281 prop_assert_eq!(slice, deserialized);
1282 }
1283 });
1284 }
1285
1286 #[test]
1287 fn test_arc_handles_drop() {
1288 let _guard = TLDropGuard::new();
1289 proptest!(proptest_cfg(), |(data in any::<DropCountedMaybeError>().prop_map(Rc::from))| {
1290 let serialized = serialize(&data).unwrap();
1291 let deserialized = deserialize(&serialized);
1292 if let Ok(deserialized) = deserialized {
1293 prop_assert_eq!(data, deserialized);
1294 }
1295 });
1296 }
1297
1298 #[test]
1299 fn test_rc_handles_drop() {
1300 let _guard = TLDropGuard::new();
1301 proptest!(proptest_cfg(), |(data in any::<DropCountedMaybeError>().prop_map(Rc::from))| {
1302 let serialized = serialize(&data).unwrap();
1303 let deserialized = deserialize(&serialized);
1304 if let Ok(deserialized) = deserialized {
1305 prop_assert_eq!(data, deserialized);
1306 }
1307 });
1308 }
1309
1310 #[test]
1311 fn test_box_handles_drop() {
1312 let _guard = TLDropGuard::new();
1313 proptest!(proptest_cfg(), |(data in any::<DropCountedMaybeError>().prop_map(Box::new))| {
1314 let serialized = serialize(&data).unwrap();
1315 let deserialized = deserialize(&serialized);
1316 if let Ok(deserialized) = deserialized {
1317 prop_assert_eq!(data, deserialized);
1318 }
1319 });
1320 }
1321
1322 #[test]
1323 fn test_array_handles_partial_drop() {
1324 let _guard = TLDropGuard::new();
1325
1326 proptest!(proptest_cfg(), |(array in proptest::array::uniform32(any::<DropCountedMaybeError>()))| {
1327 let serialized = serialize(&array).unwrap();
1328 let deserialized = <[DropCountedMaybeError; 32]>::deserialize(&serialized);
1329 if let Ok(deserialized) = deserialized {
1330 prop_assert_eq!(array, deserialized);
1331 }
1332 });
1333 }
1334
1335 #[test]
1336 fn test_uninit_builder_handles_partial_drop() {
1337 #[derive(SchemaWrite, UninitBuilder, Debug, proptest_derive::Arbitrary)]
1338 #[wincode(internal)]
1339 struct Test {
1340 a: DropCounted,
1341 b: DropCounted,
1342 c: DropCounted,
1343 }
1344
1345 {
1346 let _guard = TLDropGuard::new();
1347 proptest!(proptest_cfg(), |(test: Test)| {
1348 let serialized = serialize(&test).unwrap();
1349 let mut test = MaybeUninit::<Test>::uninit();
1350 let mut reader = serialized.as_slice();
1351 let mut builder = TestUninitBuilder::<DefaultConfig>::from_maybe_uninit_mut(&mut test);
1352 builder.read_a(reader.by_ref())?.read_b(reader.by_ref())?;
1353 prop_assert!(!builder.is_init());
1354 });
1356 }
1357
1358 #[derive(SchemaWrite, UninitBuilder, Debug, proptest_derive::Arbitrary)]
1359 #[wincode(internal)]
1360 struct TestTuple(DropCounted, DropCounted);
1362
1363 {
1364 let _guard = TLDropGuard::new();
1365 proptest!(proptest_cfg(), |(test: TestTuple)| {
1366 let serialized = serialize(&test).unwrap();
1367 let mut test = MaybeUninit::<TestTuple>::uninit();
1368 let reader = &mut serialized.as_slice();
1369 let mut builder = TestTupleUninitBuilder::<DefaultConfig>::from_maybe_uninit_mut(&mut test);
1370 builder.read_0(reader)?;
1371 prop_assert!(!builder.is_init());
1372 });
1374 }
1375 }
1376
1377 #[test]
1378 fn test_uninit_builder_nested_builder_handles_partial_drop() {
1379 #[derive(SchemaWrite, SchemaRead, UninitBuilder, Debug, proptest_derive::Arbitrary)]
1380 #[wincode(internal)]
1381 struct Inner {
1382 a: DropCounted,
1383 b: DropCounted,
1384 c: DropCounted,
1385 }
1386
1387 #[derive(SchemaWrite, UninitBuilder, Debug, proptest_derive::Arbitrary)]
1388 #[wincode(internal)]
1389 struct Test {
1390 inner: Inner,
1391 b: DropCounted,
1392 }
1393
1394 {
1395 let _guard = TLDropGuard::new();
1396 proptest!(proptest_cfg(), |(test: Test)| {
1397 let serialized = serialize(&test).unwrap();
1398 let mut test = MaybeUninit::<Test>::uninit();
1399 let mut reader = serialized.as_slice();
1400 let mut outer_builder = TestUninitBuilder::<DefaultConfig>::from_maybe_uninit_mut(&mut test);
1401 unsafe {
1402 outer_builder.init_inner_with(|inner| {
1403 let mut inner_builder = InnerUninitBuilder::<DefaultConfig>::from_maybe_uninit_mut(inner);
1404 inner_builder.read_a(reader.by_ref())?;
1405 inner_builder.read_b(reader.by_ref())?;
1406 inner_builder.read_c(reader.by_ref())?;
1407 assert!(inner_builder.is_init());
1408 inner_builder.finish();
1409 Ok(())
1410 })?;
1411 }
1412 });
1414 }
1415 }
1416
1417 #[test]
1418 fn test_uninit_builder_nested_fully_initialized() {
1419 #[derive(
1420 SchemaWrite, SchemaRead, UninitBuilder, Debug, PartialEq, Eq, proptest_derive::Arbitrary,
1421 )]
1422 #[wincode(internal)]
1423 struct Inner {
1424 a: DropCounted,
1425 b: DropCounted,
1426 c: DropCounted,
1427 }
1428
1429 #[derive(SchemaWrite, UninitBuilder, Debug, PartialEq, Eq, proptest_derive::Arbitrary)]
1430 #[wincode(internal)]
1431 struct Test {
1432 inner: Inner,
1433 b: DropCounted,
1434 }
1435
1436 {
1437 let _guard = TLDropGuard::new();
1438 proptest!(proptest_cfg(), |(test: Test)| {
1439 let serialized = serialize(&test).unwrap();
1440 let mut uninit = MaybeUninit::<Test>::uninit();
1441 let mut reader = serialized.as_slice();
1442 let mut outer_builder = TestUninitBuilder::<DefaultConfig>::from_maybe_uninit_mut(&mut uninit);
1443 unsafe {
1444 outer_builder.init_inner_with(|inner| {
1445 let mut inner_builder = InnerUninitBuilder::<DefaultConfig>::from_maybe_uninit_mut(inner);
1446 inner_builder.read_a(reader.by_ref())?;
1447 inner_builder.read_b(reader.by_ref())?;
1448 inner_builder.read_c(reader.by_ref())?;
1449 assert!(inner_builder.is_init());
1450 inner_builder.finish();
1451 Ok(())
1452 })?;
1453 }
1454 outer_builder.read_b(reader.by_ref())?;
1455 prop_assert!(outer_builder.is_init());
1456 outer_builder.finish();
1457 let init = unsafe { uninit.assume_init() };
1458 prop_assert_eq!(test, init);
1459 });
1460 }
1461 }
1462
1463 #[test]
1464 fn test_uninit_builder() {
1465 #[derive(SchemaWrite, UninitBuilder, Debug, PartialEq, Eq, proptest_derive::Arbitrary)]
1466 #[wincode(internal)]
1467 struct Test {
1468 a: Vec<u8>,
1469 b: [u8; 32],
1470 c: u64,
1471 }
1472
1473 proptest!(proptest_cfg(), |(test: Test)| {
1474 let serialized = serialize(&test).unwrap();
1475 let mut uninit = MaybeUninit::<Test>::uninit();
1476 let mut reader = serialized.as_slice();
1477 let mut builder = TestUninitBuilder::<DefaultConfig>::from_maybe_uninit_mut(&mut uninit);
1478 builder
1479 .read_a(reader.by_ref())?
1480 .read_b(reader.by_ref())?
1481 .write_c(test.c);
1482 prop_assert!(builder.is_init());
1483 builder.finish();
1484 let init = unsafe { uninit.assume_init() };
1485 prop_assert_eq!(test, init);
1486 });
1487 }
1488
1489 #[test]
1490 fn test_uninit_builder_with_type_then_const_default_generics() {
1491 #[derive(UninitBuilder)]
1492 #[wincode(internal)]
1493 #[repr(C)]
1494 struct Foo<T = u16, const N: usize = 4>
1495 where
1496 T: Copy,
1497 {
1498 marker: PhantomData<T>,
1499 bytes: [u8; N],
1500 }
1501
1502 let mut uninit = MaybeUninit::<Foo<u16, 4>>::uninit();
1503 let mut builder =
1504 FooUninitBuilder::<u16, 4, DefaultConfig>::from_maybe_uninit_mut(&mut uninit);
1505 builder.write_marker(PhantomData).write_bytes([1, 2, 3, 4]);
1506 assert!(builder.is_init());
1507 builder.finish();
1508
1509 let initialized = unsafe { uninit.assume_init() };
1511 assert_eq!(initialized.bytes, [1, 2, 3, 4]);
1512 }
1513
1514 #[test]
1515 fn test_uninit_builder_uninit_ref() {
1516 #[derive(SchemaWrite, UninitBuilder, Debug, PartialEq, Eq, proptest_derive::Arbitrary)]
1517 #[wincode(internal)]
1518 struct Test {
1519 a: Vec<u8>,
1520 b: [u8; 32],
1521 c: u64,
1522 }
1523
1524 proptest!(proptest_cfg(), |(test: Test)| {
1525 let serialized = serialize(&test).unwrap();
1526 let mut uninit = MaybeUninit::<Test>::uninit();
1527 let mut reader = serialized.as_slice();
1528 let mut builder = TestUninitBuilder::<DefaultConfig>::from_maybe_uninit_mut(&mut uninit);
1529 builder
1530 .read_a(reader.by_ref())?
1531 .read_b(reader.by_ref())?
1532 .write_c(test.c);
1533 prop_assert!(builder.is_init());
1534
1535 unsafe {
1536 prop_assert_eq!(builder.uninit_a_ref().assume_init_ref(), &test.a);
1537 prop_assert_eq!(builder.uninit_b_ref().assume_init_ref(), &test.b);
1538 prop_assert_eq!(builder.uninit_c_ref().assume_init_ref(), &test.c);
1539 }
1540
1541 builder.finish();
1542 let init = unsafe { uninit.assume_init() };
1543 prop_assert_eq!(test, init);
1544 });
1545 }
1546
1547 #[test]
1548 fn test_uninit_builder_sanity() {
1549 #[derive(
1550 SchemaWrite, SchemaRead, UninitBuilder, Debug, PartialEq, Eq, proptest_derive::Arbitrary,
1551 )]
1552 #[wincode(internal)]
1553 struct Test {
1554 a: Vec<u8>,
1555 b: [u8; 32],
1556 c: u64,
1557 }
1558
1559 proptest!(proptest_cfg(), |(test: Test)| {
1560 let serialized = serialize(&test).unwrap();
1561 let mut uninit = MaybeUninit::<Test>::uninit();
1562 let mut reader = serialized.as_slice();
1563 let mut builder = TestUninitBuilder::<DefaultConfig>::from_maybe_uninit_mut(&mut uninit);
1564 builder
1565 .read_a(reader.by_ref())?
1566 .read_b(reader.by_ref())?
1567 .write_c(test.c);
1568 prop_assert!(builder.is_init());
1569 builder.finish();
1570 let init = unsafe { uninit.assume_init() };
1571 prop_assert_eq!(test, init);
1572 });
1573 }
1574
1575 #[test]
1576 fn test_uninit_builder_with_container() {
1577 #[derive(SchemaWrite, UninitBuilder, Debug, PartialEq, Eq, proptest_derive::Arbitrary)]
1578 #[wincode(internal)]
1579 struct Test {
1580 #[wincode(with = "containers::Vec<_, UseIntLen<u16>>")]
1581 a: Vec<u8>,
1582 b: [u8; 32],
1583 c: u64,
1584 }
1585
1586 proptest!(proptest_cfg(), |(test: Test)| {
1587 let serialized = serialize(&test).unwrap();
1588 let encoded_len = u16::try_from(test.a.len()).unwrap().to_le_bytes();
1589 prop_assert_eq!(&serialized[..encoded_len.len()], &encoded_len);
1590 let mut reader = serialized.as_slice();
1591 let mut uninit = MaybeUninit::<Test>::uninit();
1592 let mut builder = TestUninitBuilder::<DefaultConfig>::from_maybe_uninit_mut(&mut uninit);
1593 builder
1594 .read_a(reader.by_ref())?
1595 .read_b(reader.by_ref())?
1596 .read_c(reader)?;
1597 prop_assert!(builder.is_init());
1598 let init_mut = unsafe { builder.into_assume_init_mut() };
1599 prop_assert_eq!(&test, init_mut);
1600 let init = unsafe { uninit.assume_init() };
1602 prop_assert_eq!(test, init);
1603 });
1604 }
1605
1606 #[test]
1607 fn test_uninit_builder_extensions_with_reference() {
1608 #[derive(Debug, PartialEq, Eq, proptest_derive::Arbitrary)]
1609 struct Test {
1610 a: Vec<u8>,
1611 b: Option<String>,
1612 }
1613
1614 #[derive(UninitBuilder, Debug, PartialEq, Eq)]
1615 #[wincode(internal)]
1616 struct TestRef<'a> {
1617 a: &'a [u8],
1618 b: Option<&'a str>,
1619 }
1620
1621 proptest!(proptest_cfg(), |(test: Test)| {
1622 let mut uninit = MaybeUninit::<TestRef>::uninit();
1623 let mut builder = TestRefUninitBuilder::<DefaultConfig>::from_maybe_uninit_mut(&mut uninit);
1624 builder
1625 .write_a(test.a.as_slice())
1626 .write_b(test.b.as_deref());
1627 prop_assert!(builder.is_init());
1628 builder.finish();
1629 let init = unsafe { uninit.assume_init() };
1630 prop_assert_eq!(test.a.as_slice(), init.a);
1631 prop_assert_eq!(test.b.as_deref(), init.b);
1632 });
1633 }
1634
1635 #[test]
1636 fn test_uninit_builder_read_borrowed() {
1637 #[derive(SchemaWrite, Debug, PartialEq, Eq, proptest_derive::Arbitrary)]
1638 #[wincode(internal)]
1639 struct Test {
1640 a: Vec<u8>,
1641 b: Option<String>,
1642 }
1643
1644 #[derive(UninitBuilder, Debug, PartialEq, Eq)]
1645 #[wincode(internal)]
1646 struct TestRef<'a> {
1647 a: &'a [u8],
1648 b: Option<&'a str>,
1649 }
1650
1651 proptest!(proptest_cfg(), |(test: Test)| {
1652 let serialized = serialize(&test).unwrap();
1653 let mut uninit = MaybeUninit::<TestRef>::uninit();
1654 let mut reader = serialized.as_slice();
1655 let mut builder = TestRefUninitBuilder::<DefaultConfig>::from_maybe_uninit_mut(&mut uninit);
1656 builder
1657 .read_a(reader.by_ref())?
1658 .read_b(reader.by_ref())?;
1659 prop_assert!(builder.is_init());
1660 let init = unsafe { builder.into_assume_init_mut() };
1661 prop_assert_eq!(test.a.as_slice(), init.a);
1662 prop_assert_eq!(test.b.as_deref(), init.b);
1663 });
1664 }
1665
1666 #[test]
1667 fn test_uninit_builder_read_owned_with_unrelated_lifetime() {
1668 #[derive(UninitBuilder, Debug, PartialEq, Eq)]
1669 #[wincode(internal)]
1670 struct Test<'a> {
1671 marker: PhantomData<&'a ()>,
1672 value: u8,
1673 }
1674
1675 fn read_short_lived(reader: &[u8]) -> Test<'static> {
1676 let mut uninit = MaybeUninit::<Test<'static>>::uninit();
1677 let mut builder =
1678 TestUninitBuilder::<DefaultConfig>::from_maybe_uninit_mut(&mut uninit);
1679 builder
1680 .write_marker(PhantomData)
1681 .read_value(reader)
1682 .unwrap();
1683 builder.finish();
1684 unsafe { uninit.assume_init() }
1686 }
1687
1688 let short_lived = vec![42];
1689 let test = read_short_lived(&short_lived);
1690 drop(short_lived);
1691
1692 assert_eq!(
1693 test,
1694 Test {
1695 marker: PhantomData,
1696 value: 42,
1697 }
1698 );
1699 }
1700
1701 #[test]
1702 fn test_uninit_builder_builder_fully_initialized() {
1703 #[derive(SchemaWrite, UninitBuilder, Debug, PartialEq, Eq, proptest_derive::Arbitrary)]
1704 #[wincode(internal)]
1705 struct Test {
1706 a: DropCounted,
1707 b: DropCounted,
1708 c: DropCounted,
1709 }
1710
1711 {
1712 let _guard = TLDropGuard::new();
1713 proptest!(proptest_cfg(), |(test: Test)| {
1714 let serialized = serialize(&test).unwrap();
1715 let mut uninit = MaybeUninit::<Test>::uninit();
1716 let mut reader = serialized.as_slice();
1717 let mut builder = TestUninitBuilder::<DefaultConfig>::from_maybe_uninit_mut(&mut uninit);
1718 builder
1719 .read_a(reader.by_ref())?
1720 .read_b(reader.by_ref())?
1721 .read_c(reader.by_ref())?;
1722 prop_assert!(builder.is_init());
1723 let init = unsafe { builder.into_assume_init_mut() };
1724 prop_assert_eq!(&test, init);
1725
1726 let init = unsafe { uninit.assume_init() };
1727 prop_assert_eq!(test, init);
1728 });
1729 }
1730
1731 #[derive(SchemaWrite, UninitBuilder, Debug, PartialEq, Eq, proptest_derive::Arbitrary)]
1732 #[wincode(internal)]
1733 struct TestTuple(DropCounted, DropCounted);
1735
1736 {
1737 let _guard = TLDropGuard::new();
1738 proptest!(proptest_cfg(), |(test: TestTuple)| {
1739 let serialized = serialize(&test).unwrap();
1740 let mut uninit = MaybeUninit::<TestTuple>::uninit();
1741 let mut reader = serialized.as_slice();
1742 let mut builder = TestTupleUninitBuilder::<DefaultConfig>::from_maybe_uninit_mut(&mut uninit);
1743 builder
1744 .read_0(reader.by_ref())?
1745 .read_1(reader.by_ref())?;
1746 assert!(builder.is_init());
1747 builder.finish();
1748
1749 let init = unsafe { uninit.assume_init() };
1750 prop_assert_eq!(test, init);
1751 });
1752 }
1753 }
1754
1755 #[test]
1756 fn test_struct_with_reference_equivalence() {
1757 #[derive(
1758 SchemaWrite, SchemaRead, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize,
1759 )]
1760 #[wincode(internal)]
1761 struct WithReference<'a> {
1762 data: &'a str,
1763 id: u64,
1764 }
1765
1766 proptest!(proptest_cfg(), |(s in any::<String>(), id in any::<u64>())| {
1767 let serialized = serialize(&WithReference { data: &s, id }).unwrap();
1768 let bincode_serialized = bincode::serialize(&WithReference { data: &s, id }).unwrap();
1769 prop_assert_eq!(&serialized, &bincode_serialized);
1770 let deserialized: WithReference = deserialize(&serialized).unwrap();
1771 let bincode_deserialized: WithReference = bincode::deserialize(&bincode_serialized).unwrap();
1772 prop_assert_eq!(deserialized, bincode_deserialized);
1773 });
1774 }
1775
1776 #[test]
1777 fn test_skipped_fields() {
1778 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, Eq, proptest_derive::Arbitrary)]
1779 #[wincode(internal)]
1780 struct Test {
1781 a: StructZeroCopy,
1782 #[wincode(skip)]
1783 b: [u8; 32],
1784 c: StructStatic,
1785 #[wincode(skip(default_val = 345))]
1786 d: u32,
1787 }
1788
1789 let expected = TypeMeta::Static {
1790 size: size_of::<StructZeroCopy>()
1791 + <StructStatic as SchemaWrite<DefaultConfig>>::TYPE_META.size_assert_static(),
1792 zero_copy: false,
1793 };
1794 assert_eq!(<Test as SchemaWrite<DefaultConfig>>::TYPE_META, expected);
1795
1796 proptest!(proptest_cfg(), |(test: Test)| {
1797 let mut serialized = serialize(&test).unwrap();
1798 let mut uninit_zeroed = MaybeUninit::<Test>::uninit();
1799 Test::deserialize_into(serialized.as_mut(), &mut uninit_zeroed).unwrap();
1800 let deserialized = unsafe { uninit_zeroed.assume_init() };
1801 assert_eq!(deserialized.b, [0; 32]);
1802 assert_eq!(deserialized.d, 345);
1803 let reinitialized = Test {
1804 b: test.b,
1805 d: test.d,
1806 ..deserialized
1807 };
1808 prop_assert_eq!(reinitialized, test);
1809 });
1810
1811 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, Eq, proptest_derive::Arbitrary)]
1812 #[wincode(internal)]
1813 struct TestTuple(StructZeroCopy, #[wincode(skip)] u64, u32);
1814
1815 let expected = TypeMeta::Static {
1816 size: size_of::<StructZeroCopy>() + size_of::<u32>(),
1817 zero_copy: false,
1818 };
1819 assert_eq!(
1820 <TestTuple as SchemaWrite<DefaultConfig>>::TYPE_META,
1821 expected
1822 );
1823
1824 proptest!(proptest_cfg(), |(test: TestTuple)| {
1825 let mut serialized = serialize(&test).unwrap();
1826 let mut uninit_zeroed = MaybeUninit::<TestTuple>::uninit();
1827 TestTuple::deserialize_into(serialized.as_mut(), &mut uninit_zeroed).unwrap();
1828 let deserialized = unsafe { uninit_zeroed.assume_init() };
1829 assert_eq!(deserialized.1, 0);
1830 let reinitialized = TestTuple(deserialized.0, test.1, deserialized.2);
1831 prop_assert_eq!(reinitialized, test);
1832 });
1833
1834 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, Eq, proptest_derive::Arbitrary)]
1835 #[wincode(internal)]
1836 enum TestEnum {
1837 X([u64; 17], u8),
1838 Y(Test),
1839 Z(([u64; 16], u8), #[wincode(skip(default_val = 9))] u8, u64),
1840 W {
1841 a: u8,
1842 #[wincode(skip(default_val = 123))]
1843 b: u16,
1844 c: [u64; 17],
1845 },
1846 }
1847 let expected = TypeMeta::Static {
1848 size: size_of::<u32>() + size_of::<u64>() * 17 + size_of::<u8>(),
1850 zero_copy: false,
1851 };
1852 assert_eq!(
1853 <TestEnum as SchemaWrite<DefaultConfig>>::TYPE_META,
1854 expected
1855 );
1856
1857 proptest!(proptest_cfg(), |(test: TestEnum)| {
1858 let mut serialized = serialize(&test).unwrap();
1859 let mut uninit_zeroed = MaybeUninit::<TestEnum>::uninit();
1860 TestEnum::deserialize_into(serialized.as_mut(), &mut uninit_zeroed).unwrap();
1861
1862 let deserialized = unsafe { uninit_zeroed.assume_init() };
1863 let reinitialized = match (deserialized, &test) {
1864 (TestEnum::Y(deserialized_y), TestEnum::Y(test_y)) => {
1865 assert_eq!(deserialized_y.b, [0; 32]);
1866 assert_eq!(deserialized_y.d, 345);
1867 TestEnum::Y(Test {
1868 b: test_y.b,
1869 d: test_y.d,
1870 ..deserialized_y
1871 })
1872 },
1873 (TestEnum::Z(d_0, d_1, d_2), TestEnum::Z(_, t_1, _)) => {
1874 assert_eq!(d_1, 9);
1875 TestEnum::Z(d_0, *t_1, d_2)
1876 },
1877 (TestEnum::W { a: d_a, b: d_b, c: d_c }, TestEnum::W { a: _, b: test_b, c: _ }) => {
1878 assert_eq!(d_b, 123);
1879 TestEnum::W {
1880 a: d_a,
1881 b: *test_b,
1882 c: d_c,
1883 }
1884 },
1885 (other, _) => other
1886 };
1887 prop_assert_eq!(reinitialized, test);
1888 });
1889
1890 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, Eq, proptest_derive::Arbitrary)]
1891 #[wincode(internal)]
1892 #[repr(C)]
1893 struct TestZeroCopy {
1894 a: StructZeroCopy,
1895 #[wincode(skip)]
1896 b: (),
1897 c: [u8; 16],
1898 }
1899 assert_eq!(
1900 <TestZeroCopy as SchemaWrite<DefaultConfig>>::TYPE_META,
1901 TypeMeta::Static {
1902 size: size_of::<StructZeroCopy>() + 16,
1903 zero_copy: true,
1904 }
1905 );
1906
1907 proptest!(proptest_cfg(), |(test: TestZeroCopy)| {
1908 let mut serialized = serialize(&test).unwrap();
1909 let mut uninit_zeroed = MaybeUninit::<TestZeroCopy>::uninit();
1910 TestZeroCopy::deserialize_into(serialized.as_mut(), &mut uninit_zeroed).unwrap();
1911 let deserialized = unsafe { uninit_zeroed.assume_init() };
1912 prop_assert_eq!(deserialized, test);
1913 });
1914
1915 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, Eq, proptest_derive::Arbitrary)]
1916 #[wincode(internal)]
1917 #[repr(C)]
1918 struct TestNonZeroCopy {
1919 a: StructZeroCopy,
1920 #[wincode(skip(default_val = [1u8; 16]))]
1921 b: [u8; 16],
1922 }
1923 assert_eq!(
1924 <TestNonZeroCopy as SchemaWrite<DefaultConfig>>::TYPE_META,
1925 TypeMeta::Static {
1926 size: size_of::<StructZeroCopy>(),
1927 zero_copy: false,
1928 }
1929 );
1930
1931 proptest!(proptest_cfg(), |(test: TestNonZeroCopy)| {
1932 let mut serialized = serialize(&test).unwrap();
1933 let mut uninit_zeroed = MaybeUninit::<TestNonZeroCopy>::uninit();
1934 TestNonZeroCopy::deserialize_into(serialized.as_mut(), &mut uninit_zeroed).unwrap();
1935 let deserialized = unsafe { uninit_zeroed.assume_init() };
1936 assert_eq!(deserialized.b, [1u8; 16]);
1937 let reinitialized = TestNonZeroCopy {
1938 b: test.b,
1939 ..deserialized
1940 };
1941 prop_assert_eq!(reinitialized, test);
1942 });
1943 }
1944
1945 #[test]
1946 fn test_enum_equivalence() {
1947 #[derive(
1948 SchemaWrite,
1949 SchemaRead,
1950 Debug,
1951 PartialEq,
1952 Eq,
1953 serde::Serialize,
1954 serde::Deserialize,
1955 Clone,
1956 proptest_derive::Arbitrary,
1957 )]
1958 #[wincode(internal)]
1959 enum Enum {
1960 A { name: String, id: u64 },
1961 B(String, Vec<u8>),
1962 C,
1963 }
1964
1965 proptest!(proptest_cfg(), |(e: Enum)| {
1966 let serialized = serialize(&e).unwrap();
1967 let bincode_serialized = bincode::serialize(&e).unwrap();
1968 prop_assert_eq!(&serialized, &bincode_serialized);
1969 let deserialized: Enum = deserialize(&serialized).unwrap();
1970 let bincode_deserialized: Enum = bincode::deserialize(&bincode_serialized).unwrap();
1971 prop_assert_eq!(deserialized, bincode_deserialized);
1972 });
1973 }
1974
1975 #[test]
1976 fn enum_with_tag_encoding_roundtrip() {
1977 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, proptest_derive::Arbitrary)]
1978 #[wincode(internal, tag_encoding = "u8")]
1979 enum Enum {
1980 A { name: String, id: u64 },
1981 B(String, Vec<u8>),
1982 C,
1983 }
1984
1985 proptest!(proptest_cfg(), |(e: Enum)| {
1986 let serialized = serialize(&e).unwrap();
1987 let deserialized: Enum = deserialize(&serialized).unwrap();
1988 prop_assert_eq!(deserialized, e);
1989 });
1990 }
1991
1992 #[test]
1993 fn enum_with_custom_tag_roundtrip() {
1994 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, proptest_derive::Arbitrary)]
1995 #[wincode(internal)]
1996 enum Enum {
1997 #[wincode(tag = 5)]
1998 A { name: String, id: u64 },
1999 #[wincode(tag = 8)]
2000 B(String, Vec<u8>),
2001 #[wincode(tag = 13)]
2002 C,
2003 }
2004
2005 proptest!(proptest_cfg(), |(e: Enum)| {
2006 let serialized = serialize(&e).unwrap();
2007 let deserialized: Enum = deserialize(&serialized).unwrap();
2008 prop_assert_eq!(deserialized, e);
2009 });
2010
2011 proptest!(proptest_cfg(), |(e: Enum)| {
2012 let serialized = serialize(&e).unwrap();
2013 let int: u32 = match e {
2014 Enum::A { .. } => 5,
2015 Enum::B(..) => 8,
2016 Enum::C => 13,
2017 };
2018 prop_assert_eq!(&int.to_le_bytes(), &serialized[..4]);
2019 });
2020 }
2021
2022 #[test]
2023 fn unit_enum_with_tag_encoding_static_size() {
2024 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq)]
2025 #[wincode(internal, tag_encoding = "u8")]
2026 enum Enum {
2027 A,
2028 B,
2029 C,
2030 }
2031
2032 assert!(matches!(
2033 <Enum as SchemaWrite<DefaultConfig>>::TYPE_META,
2034 TypeMeta::Static {
2035 size: 1,
2036 zero_copy: false
2037 }
2038 ));
2039
2040 assert!(matches!(
2041 <Enum as SchemaRead<'_, DefaultConfig>>::TYPE_META,
2042 TypeMeta::Static {
2043 size: 1,
2044 zero_copy: false
2045 }
2046 ));
2047 }
2048
2049 #[test]
2050 fn unit_enum_with_static_size() {
2051 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq)]
2052 #[wincode(internal)]
2053 enum Enum {
2054 A,
2055 B,
2056 C,
2057 }
2058
2059 assert!(matches!(
2060 <Enum as SchemaWrite<DefaultConfig>>::TYPE_META,
2061 TypeMeta::Static {
2062 size: 4,
2063 zero_copy: false
2064 }
2065 ));
2066
2067 assert!(matches!(
2068 <Enum as SchemaRead<'_, DefaultConfig>>::TYPE_META,
2069 TypeMeta::Static {
2070 size: 4,
2071 zero_copy: false
2072 }
2073 ));
2074 }
2075
2076 #[test]
2077 fn enum_tag_encoding() {
2078 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, proptest_derive::Arbitrary)]
2079 #[wincode(internal, tag_encoding = "u8")]
2080 enum EnumU8 {
2081 A,
2082 B,
2083 C,
2084 }
2085
2086 proptest!(proptest_cfg(), |(e: EnumU8)| {
2087 let serialized = serialize(&e).unwrap();
2088 let int = e as u8;
2089 prop_assert_eq!(&int.to_le_bytes(), &serialized[..]);
2090 });
2091
2092 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, proptest_derive::Arbitrary)]
2093 #[wincode(internal, tag_encoding = "u8")]
2094 enum EnumTupleU8 {
2095 A(u64),
2096 B(StructStatic),
2097 C(StructNonStatic),
2098 }
2099
2100 proptest!(proptest_cfg(), |(e: EnumTupleU8)| {
2101 let serialized = serialize(&e).unwrap();
2102 let int: u8 = match e {
2103 EnumTupleU8::A(_) => 0,
2104 EnumTupleU8::B(_) => 1,
2105 EnumTupleU8::C(_) => 2,
2106 };
2107 prop_assert_eq!(&int.to_le_bytes(), &serialized[..1]);
2108 });
2109
2110 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, proptest_derive::Arbitrary)]
2111 #[wincode(internal, tag_encoding = "u8")]
2112 enum EnumRecordU8 {
2113 A { id: u64 },
2114 B { data: StructStatic },
2115 C { data: StructNonStatic },
2116 }
2117
2118 proptest!(proptest_cfg(), |(e: EnumRecordU8)| {
2119 let serialized = serialize(&e).unwrap();
2120 let int: u8 = match e {
2121 EnumRecordU8::A { .. } => 0,
2122 EnumRecordU8::B { .. } => 1,
2123 EnumRecordU8::C { .. } => 2,
2124 };
2125 prop_assert_eq!(&int.to_le_bytes(), &serialized[..1]);
2126 });
2127 }
2128
2129 #[test]
2130 fn enum_static_uniform_variants() {
2131 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, proptest_derive::Arbitrary)]
2132 #[wincode(internal)]
2133 enum Enum {
2134 A {
2135 a: u64,
2136 },
2137 B {
2138 x: u32,
2139 y: u32,
2140 },
2141 C {
2142 a: u8,
2143 b: u8,
2144 c: u8,
2145 d: u8,
2146 e: u8,
2147 f: u8,
2148 g: u8,
2149 h: u8,
2150 },
2151 }
2152
2153 assert_eq!(
2154 <Enum as SchemaWrite<DefaultConfig>>::TYPE_META,
2155 TypeMeta::Static {
2156 size: 8 + 4,
2158 zero_copy: false
2159 }
2160 );
2161 assert_eq!(
2162 <Enum as SchemaRead<'_, DefaultConfig>>::TYPE_META,
2163 TypeMeta::Static {
2164 size: 8 + 4,
2166 zero_copy: false
2167 }
2168 );
2169
2170 proptest!(proptest_cfg(), |(e: Enum)| {
2171 let serialized = serialize(&e).unwrap();
2172 let deserialized: Enum = deserialize(&serialized).unwrap();
2173 prop_assert_eq!(deserialized, e);
2174 });
2175 }
2176
2177 #[test]
2178 fn enum_dynamic_non_uniform_variants() {
2179 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, proptest_derive::Arbitrary)]
2180 #[wincode(internal)]
2181 enum Enum {
2182 A { a: u64 },
2183 B { x: u32, y: u32 },
2184 C { a: u8, b: u8 },
2185 }
2186
2187 assert_eq!(
2188 <Enum as SchemaWrite<DefaultConfig>>::TYPE_META,
2189 TypeMeta::Dynamic
2190 );
2191 assert_eq!(
2192 <Enum as SchemaRead<'_, DefaultConfig>>::TYPE_META,
2193 TypeMeta::Dynamic
2194 );
2195
2196 proptest!(proptest_cfg(), |(e: Enum)| {
2197 let serialized = serialize(&e).unwrap();
2198 let deserialized: Enum = deserialize(&serialized).unwrap();
2199 prop_assert_eq!(deserialized, e);
2200 });
2201 }
2202
2203 #[test]
2204 fn enum_single_variant_type_meta_pass_thru() {
2205 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, proptest_derive::Arbitrary)]
2206 #[wincode(internal)]
2207 enum Enum {
2208 A { a: u8, b: [u8; 32] },
2209 }
2210
2211 assert_eq!(
2214 <Enum as SchemaWrite<DefaultConfig>>::TYPE_META,
2215 TypeMeta::Static {
2216 size: 1 + 32 + 4,
2217 zero_copy: false
2218 }
2219 );
2220 assert_eq!(
2221 <Enum as SchemaRead<'_, DefaultConfig>>::TYPE_META,
2222 TypeMeta::Static {
2223 size: 1 + 32 + 4,
2224 zero_copy: false
2225 }
2226 );
2227 }
2228
2229 #[test]
2230 fn enum_unit_and_non_unit_dynamic() {
2231 #[derive(
2232 SchemaWrite,
2233 SchemaRead,
2234 Debug,
2235 PartialEq,
2236 proptest_derive::Arbitrary,
2237 serde::Serialize,
2238 serde::Deserialize,
2239 )]
2240 #[wincode(internal)]
2241 enum Enum {
2242 Unit,
2243 NonUnit(u8),
2244 }
2245
2246 assert_eq!(
2247 <Enum as SchemaWrite<DefaultConfig>>::TYPE_META,
2248 TypeMeta::Dynamic
2249 );
2250 assert_eq!(
2251 <Enum as SchemaRead<'_, DefaultConfig>>::TYPE_META,
2252 TypeMeta::Dynamic
2253 );
2254
2255 proptest!(proptest_cfg(), |(e: Enum)| {
2256 let serialized = serialize(&e).unwrap();
2257 let bincode_serialized = bincode::serialize(&e).unwrap();
2258 prop_assert_eq!(&serialized, &bincode_serialized);
2259
2260 let deserialized: Enum = deserialize(&serialized).unwrap();
2261 let bincode_deserialized: Enum = bincode::deserialize(&bincode_serialized).unwrap();
2262 prop_assert_eq!(&deserialized, &bincode_deserialized);
2263 prop_assert_eq!(deserialized, e);
2264 });
2265 }
2266
2267 #[test]
2268 fn test_enum_config_discriminant_u8() {
2269 let config = Configuration::default().with_tag_encoding::<u8>();
2270
2271 #[derive(SchemaRead, SchemaWrite, Debug, PartialEq, Eq, proptest_derive::Arbitrary)]
2272 #[wincode(internal)]
2273 enum Enum {
2274 A,
2275 B,
2276 }
2277
2278 assert_eq!(
2279 <Enum as SchemaRead<'_, _>>::type_meta(config),
2280 TypeMeta::Static {
2281 size: 1,
2282 zero_copy: false
2283 }
2284 );
2285
2286 assert_eq!(
2287 <Enum as SchemaWrite<_>>::type_meta(config),
2288 TypeMeta::Static {
2289 size: 1,
2290 zero_copy: false
2291 }
2292 );
2293
2294 proptest!(proptest_cfg(), |(e: Enum)| {
2295 let serialized = config::serialize(&e, config).unwrap();
2296 prop_assert_eq!(serialized.len(), 1);
2297 match e {
2298 Enum::A => prop_assert_eq!(serialized[0], 0),
2299 Enum::B => prop_assert_eq!(serialized[0], 1),
2300 }
2301 let deserialized: Enum = config::deserialize(&serialized, config).unwrap();
2302 prop_assert_eq!(deserialized, e);
2303 });
2304 }
2305
2306 #[test]
2307 fn test_chained_config_preserves_tag_encoding() {
2308 let config = Configuration::default()
2309 .with_tag_encoding::<u8>()
2310 .with_big_endian()
2311 .with_preallocation_size_limit::<64>();
2312
2313 #[derive(SchemaRead, SchemaWrite, Debug, PartialEq, Eq)]
2314 #[wincode(internal)]
2315 enum Enum {
2316 A,
2317 B,
2318 }
2319
2320 assert_eq!(
2321 <Enum as SchemaRead<'_, _>>::type_meta(config),
2322 TypeMeta::Static {
2323 size: 1,
2324 zero_copy: false
2325 }
2326 );
2327
2328 assert_eq!(
2329 <Enum as SchemaWrite<_>>::type_meta(config),
2330 TypeMeta::Static {
2331 size: 1,
2332 zero_copy: false
2333 }
2334 );
2335
2336 let serialized = config::serialize(&Enum::B, config).unwrap();
2337 assert_eq!(serialized, [1]);
2338
2339 let deserialized: Enum = config::deserialize(&serialized, config).unwrap();
2340 assert_eq!(deserialized, Enum::B);
2341 }
2342
2343 #[test]
2344 fn test_enum_config_discriminant_override() {
2345 let config = Configuration::default().with_tag_encoding::<u8>();
2346
2347 #[derive(SchemaRead, SchemaWrite, Debug, PartialEq, Eq, proptest_derive::Arbitrary)]
2348 #[wincode(internal, tag_encoding = "u32")]
2349 enum Enum {
2350 A,
2351 B,
2352 }
2353
2354 assert_eq!(
2355 <Enum as SchemaRead<'_, _>>::type_meta(config),
2356 TypeMeta::Static {
2357 size: 4,
2358 zero_copy: false
2359 }
2360 );
2361
2362 assert_eq!(
2363 <Enum as SchemaWrite<_>>::type_meta(config),
2364 TypeMeta::Static {
2365 size: 4,
2366 zero_copy: false
2367 }
2368 );
2369
2370 proptest!(proptest_cfg(), |(e: Enum)| {
2371 let serialized = config::serialize(&e, config).unwrap();
2372 prop_assert_eq!(serialized.len(), 4);
2373 let discriminant = u32::from_le_bytes(serialized[0..4].try_into().unwrap());
2374 match e {
2375 Enum::A => prop_assert_eq!(discriminant, 0u32),
2376 Enum::B => prop_assert_eq!(discriminant, 1u32),
2377 }
2378 let deserialized: Enum = config::deserialize(&serialized, config).unwrap();
2379 prop_assert_eq!(deserialized, e);
2380 });
2381 }
2382
2383 #[test]
2384 fn test_enum_config_discriminant_u8_custom_tag() {
2385 let config = Configuration::default().with_tag_encoding::<u8>();
2386
2387 #[derive(SchemaRead, SchemaWrite, Debug, PartialEq, Eq, proptest_derive::Arbitrary)]
2388 #[wincode(internal)]
2389 enum Enum {
2390 #[wincode(tag = 2)]
2391 A,
2392 #[wincode(tag = 3)]
2393 B,
2394 #[wincode(tag = 5)]
2395 C,
2396 }
2397
2398 proptest!(proptest_cfg(), |(e: Enum)| {
2399 let serialized = config::serialize(&e, config).unwrap();
2400 prop_assert_eq!(serialized.len(), 1);
2401 match e {
2402 Enum::A => prop_assert_eq!(serialized[0], 2),
2403 Enum::B => prop_assert_eq!(serialized[0], 3),
2404 Enum::C => prop_assert_eq!(serialized[0], 5),
2405 }
2406 let deserialized: Enum = config::deserialize(&serialized, config).unwrap();
2407 prop_assert_eq!(deserialized, e);
2408 });
2409 }
2410
2411 #[test]
2412 fn test_enum_tag_overflow_size_of_matches_write() {
2413 let u8_tag_cfg = Configuration::default().with_tag_encoding::<u8>();
2416
2417 #[derive(SchemaWrite)]
2418 #[wincode(internal)]
2419 enum NarrowTagEnum {
2420 #[wincode(tag = 0)]
2421 Fits(u8),
2422 #[wincode(tag = 256)]
2423 Overflows(u8),
2424 }
2425
2426 let fits = NarrowTagEnum::Fits(1);
2427 assert_eq!(config::serialized_size(&fits, u8_tag_cfg).unwrap(), 2);
2428 assert_eq!(config::serialize(&fits, u8_tag_cfg).unwrap(), [0, 1]);
2429
2430 let overflow = NarrowTagEnum::Overflows(1);
2431 assert!(matches!(
2432 config::serialize(&overflow, u8_tag_cfg),
2433 Err(WriteError::TagEncodingOverflow(_))
2434 ));
2435 assert!(matches!(
2436 config::serialize_into(&mut vec![], &overflow, u8_tag_cfg),
2437 Err(WriteError::TagEncodingOverflow(_))
2438 ));
2439 assert!(matches!(
2440 config::serialized_size(&overflow, u8_tag_cfg),
2441 Err(WriteError::TagEncodingOverflow(_))
2442 ));
2443 }
2444
2445 #[test]
2446 fn test_phantom_data() {
2447 let val = PhantomData::<StructStatic>;
2448 let serialized = serialize(&val).unwrap();
2449 let bincode_serialized = bincode::serialize(&val).unwrap();
2450 assert_eq!(&serialized, &bincode_serialized);
2451 assert_eq!(
2452 <PhantomData<StructStatic> as SchemaWrite<DefaultConfig>>::size_of(&val).unwrap(),
2453 bincode::serialized_size(&val).unwrap() as usize
2454 );
2455 let deserialized: PhantomData<StructStatic> = deserialize(&serialized).unwrap();
2456 let bincode_deserialized: PhantomData<StructStatic> =
2457 bincode::deserialize(&bincode_serialized).unwrap();
2458 assert_eq!(deserialized, bincode_deserialized);
2459 }
2460
2461 #[test]
2462 fn test_unit() {
2463 let serialized = serialize(&()).unwrap();
2464 let bincode_serialized = bincode::serialize(&()).unwrap();
2465 assert_eq!(&serialized, &bincode_serialized);
2466 assert_eq!(
2467 <() as SchemaWrite<DefaultConfig>>::size_of(&()).unwrap(),
2468 bincode::serialized_size(&()).unwrap() as usize
2469 );
2470 assert!(deserialize::<()>(&serialized).is_ok());
2471 assert!(bincode::deserialize::<()>(&bincode_serialized).is_ok());
2472 }
2473
2474 #[test]
2475 fn test_duration_varint_type_meta_dynamic() {
2476 let config = Configuration::default().with_varint_encoding();
2477
2478 assert_eq!(
2479 <Duration as SchemaWrite<_>>::type_meta(config),
2480 TypeMeta::Dynamic
2481 );
2482 assert_eq!(
2483 <Duration as SchemaRead<'_, _>>::type_meta(config),
2484 TypeMeta::Dynamic
2485 );
2486
2487 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, Eq)]
2488 #[wincode(internal)]
2489 struct WithDuration {
2490 a: u8,
2491 d: Duration,
2492 b: u8,
2493 }
2494
2495 assert_eq!(
2496 <WithDuration as SchemaWrite<_>>::type_meta(config),
2497 TypeMeta::Dynamic
2498 );
2499 assert_eq!(
2500 <WithDuration as SchemaRead<'_, _>>::type_meta(config),
2501 TypeMeta::Dynamic
2502 );
2503
2504 let val = WithDuration {
2505 a: 1,
2506 d: Duration::new(0, 0),
2507 b: 2,
2508 };
2509
2510 assert_eq!(config::serialized_size(&val.d, config).unwrap(), 2);
2512
2513 let mut buf = [0xAAu8; 13];
2516 let written = {
2517 let buf_len = buf.len();
2518 let mut writer: &mut [u8] = &mut buf;
2519 config::serialize_into(&mut writer, &val, config).unwrap();
2520 buf_len - writer.len()
2521 };
2522 assert_eq!(written, 4);
2523 assert_eq!(&buf[..written], &[1, 0, 0, 2]);
2524 assert!(buf[written..].iter().all(|&b| b == 0xAA));
2525
2526 let roundtrip: WithDuration = config::deserialize(&buf[..written], config).unwrap();
2527 assert_eq!(roundtrip, val);
2528 }
2529
2530 #[test]
2531 fn test_system_time_varint_type_meta_dynamic() {
2532 let config = Configuration::default().with_varint_encoding();
2533
2534 assert_eq!(
2535 <SystemTime as SchemaWrite<_>>::type_meta(config),
2536 TypeMeta::Dynamic
2537 );
2538 assert_eq!(
2539 <SystemTime as SchemaRead<'_, _>>::type_meta(config),
2540 TypeMeta::Dynamic
2541 );
2542
2543 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, Eq)]
2544 #[wincode(internal)]
2545 struct WithSystemTime {
2546 a: u8,
2547 t: SystemTime,
2548 b: u8,
2549 }
2550
2551 assert_eq!(
2552 <WithSystemTime as SchemaWrite<_>>::type_meta(config),
2553 TypeMeta::Dynamic
2554 );
2555 assert_eq!(
2556 <WithSystemTime as SchemaRead<'_, _>>::type_meta(config),
2557 TypeMeta::Dynamic
2558 );
2559
2560 let val = WithSystemTime {
2561 a: 1,
2562 t: UNIX_EPOCH,
2563 b: 2,
2564 };
2565
2566 assert_eq!(config::serialized_size(&val.t, config).unwrap(), 2);
2568
2569 let mut buf = [0xAAu8; 13];
2570 let written = {
2571 let buf_len = buf.len();
2572 let mut writer: &mut [u8] = &mut buf;
2573 config::serialize_into(&mut writer, &val, config).unwrap();
2574 buf_len - writer.len()
2575 };
2576 assert_eq!(written, 4);
2577 assert_eq!(&buf[..written], &[1, 0, 0, 2]);
2578 assert!(buf[written..].iter().all(|&b| b == 0xAA));
2579
2580 let roundtrip: WithSystemTime = config::deserialize(&buf[..written], config).unwrap();
2581 assert_eq!(roundtrip, val);
2582 }
2583
2584 #[test]
2585 fn test_borrowed_bytes() {
2586 #[derive(
2587 SchemaWrite, SchemaRead, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize,
2588 )]
2589 #[wincode(internal)]
2590 struct BorrowedBytes<'a> {
2591 bytes: &'a [u8],
2592 }
2593
2594 proptest!(proptest_cfg(), |(bytes in proptest::collection::vec(any::<u8>(), 0..=100))| {
2595 let val = BorrowedBytes { bytes: &bytes };
2596 let bincode_serialized = bincode::serialize(&val).unwrap();
2597 let schema_serialized = serialize(&val).unwrap();
2598 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2599 let bincode_deserialized: BorrowedBytes = bincode::deserialize(&bincode_serialized).unwrap();
2600 let schema_deserialized: BorrowedBytes = deserialize(&schema_serialized).unwrap();
2601 prop_assert_eq!(&val, &bincode_deserialized);
2602 prop_assert_eq!(val, schema_deserialized);
2603 });
2604 }
2605
2606 #[test]
2607 fn test_boxed_slice_pod_drop() {
2608 #[derive(proptest_derive::Arbitrary, Debug, Clone, Copy)]
2609 #[allow(dead_code)]
2610 struct Signature([u8; 64]);
2611
2612 pod_wrapper! {
2613 unsafe struct PodSignature(Signature);
2614 }
2615
2616 type Target = containers::Box<[PodSignature], BincodeLen>;
2617 proptest!(proptest_cfg(), |(slice in proptest::collection::vec(any::<Signature>(), 1..=32).prop_map(|vec| vec.into_boxed_slice()))| {
2618 let serialized = Target::serialize(&slice).unwrap();
2619 let deserialized = Target::deserialize(&serialized[..serialized.len() - 32]);
2622 prop_assert!(deserialized.is_err());
2623 });
2624 }
2625
2626 #[test]
2627 fn test_zero_copy_padding_disqualification() {
2628 #[derive(SchemaWrite, SchemaRead)]
2629 #[wincode(internal)]
2630 #[repr(C, align(4))]
2631 struct Padded {
2632 a: u8,
2633 }
2634
2635 assert!(matches!(
2636 <Padded as SchemaWrite<DefaultConfig>>::TYPE_META,
2637 TypeMeta::Static {
2638 size: 1,
2640 zero_copy: false
2642 }
2643 ));
2644
2645 assert!(matches!(
2646 <Padded as SchemaRead<'_, DefaultConfig>>::TYPE_META,
2647 TypeMeta::Static {
2648 size: 1,
2650 zero_copy: false
2652 }
2653 ));
2654 }
2655
2656 proptest! {
2657 #![proptest_config(proptest_cfg())]
2658
2659 #[test]
2660 fn test_char(val in any::<char>()) {
2661 let bincode_serialized = bincode::serialize(&val).unwrap();
2662 let schema_serialized = serialize(&val).unwrap();
2663 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2664 prop_assert_eq!(<char as SchemaWrite<DefaultConfig>>::size_of(&val).unwrap(), bincode::serialized_size(&val).unwrap() as usize);
2665
2666 let bincode_deserialized: char = bincode::deserialize(&bincode_serialized).unwrap();
2667 let schema_deserialized: char = deserialize(&schema_serialized).unwrap();
2668 prop_assert_eq!(val, bincode_deserialized);
2669 prop_assert_eq!(val, schema_deserialized);
2670 }
2671
2672 #[test]
2673 fn test_vec_elem_static(vec in proptest::collection::vec(any::<StructStatic>(), 0..=100)) {
2674 let bincode_serialized = bincode::serialize(&vec).unwrap();
2675 let schema_serialized = serialize(&vec).unwrap();
2676 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2677
2678 let bincode_deserialized: Vec<StructStatic> = bincode::deserialize(&bincode_serialized).unwrap();
2679 let schema_deserialized: Vec<StructStatic> = deserialize(&schema_serialized).unwrap();
2680 prop_assert_eq!(&vec, &bincode_deserialized);
2681 prop_assert_eq!(vec, schema_deserialized);
2682 }
2683
2684 #[test]
2685 fn test_vec_elem_zero_copy(vec in proptest::collection::vec(any::<StructZeroCopy>(), 0..=100)) {
2686 let bincode_serialized = bincode::serialize(&vec).unwrap();
2687 let schema_serialized = serialize(&vec).unwrap();
2688 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2689
2690 let bincode_deserialized: Vec<StructZeroCopy> = bincode::deserialize(&bincode_serialized).unwrap();
2691 let schema_deserialized: Vec<StructZeroCopy> = deserialize(&schema_serialized).unwrap();
2692 prop_assert_eq!(&vec, &bincode_deserialized);
2693 prop_assert_eq!(vec, schema_deserialized);
2694 }
2695
2696 #[test]
2697 fn test_vec_elem_non_static(vec in proptest::collection::vec(any::<StructNonStatic>(), 0..=16)) {
2698 let bincode_serialized = bincode::serialize(&vec).unwrap();
2699 let schema_serialized = serialize(&vec).unwrap();
2700 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2701
2702 let bincode_deserialized: Vec<StructNonStatic> = bincode::deserialize(&bincode_serialized).unwrap();
2703 let schema_deserialized: Vec<StructNonStatic> = deserialize(&schema_serialized).unwrap();
2704 prop_assert_eq!(&vec, &bincode_deserialized);
2705 prop_assert_eq!(vec, schema_deserialized);
2706 }
2707
2708 #[test]
2709 fn test_vec_elem_bytes(vec in proptest::collection::vec(any::<u8>(), 0..=100)) {
2710 let bincode_serialized = bincode::serialize(&vec).unwrap();
2711 let schema_serialized = serialize(&vec).unwrap();
2712 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2713
2714 let bincode_deserialized: Vec<u8> = bincode::deserialize(&bincode_serialized).unwrap();
2715 let schema_deserialized: Vec<u8> = deserialize(&schema_serialized).unwrap();
2716 prop_assert_eq!(&vec, &bincode_deserialized);
2717 prop_assert_eq!(vec, schema_deserialized);
2718 }
2719
2720 #[test]
2721 fn test_serialize_slice(slice in proptest::collection::vec(any::<StructStatic>(), 0..=100)) {
2722 let bincode_serialized = bincode::serialize(slice.as_slice()).unwrap();
2723 let schema_serialized = serialize(slice.as_slice()).unwrap();
2724 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2725 }
2726
2727 #[test]
2728 fn test_vec_pod(vec in proptest::collection::vec(any::<[u8; 32]>(), 0..=100)) {
2729 let bincode_serialized = bincode::serialize(&vec).unwrap();
2730 let schema_serialized = serialize(&vec).unwrap();
2731 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2732
2733 let bincode_deserialized: Vec<[u8; 32]> = bincode::deserialize(&bincode_serialized).unwrap();
2734 let schema_deserialized: Vec<[u8; 32]> = deserialize(&schema_serialized).unwrap();
2735 prop_assert_eq!(&vec, &bincode_deserialized);
2736 prop_assert_eq!(vec, schema_deserialized);
2737 }
2738
2739 #[test]
2740 fn test_vec_deque_elem_static(vec in proptest::collection::vec_deque(any::<StructStatic>(), 0..=100)) {
2741 let bincode_serialized = bincode::serialize(&vec).unwrap();
2742 let schema_serialized = serialize(&vec).unwrap();
2743 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2744
2745 let bincode_deserialized: VecDeque<StructStatic> = bincode::deserialize(&bincode_serialized).unwrap();
2746 let schema_deserialized: VecDeque<StructStatic> = deserialize(&schema_serialized).unwrap();
2747 prop_assert_eq!(&vec, &bincode_deserialized);
2748 prop_assert_eq!(vec, schema_deserialized);
2749 }
2750
2751 #[test]
2752 fn test_vec_deque_elem_non_static(vec in proptest::collection::vec_deque(any::<StructNonStatic>(), 0..=16)) {
2753 let bincode_serialized = bincode::serialize(&vec).unwrap();
2754 let schema_serialized = serialize(&vec).unwrap();
2755 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2756
2757 let bincode_deserialized: VecDeque<StructNonStatic> = bincode::deserialize(&bincode_serialized).unwrap();
2758 let schema_deserialized: VecDeque<StructNonStatic> = deserialize(&schema_serialized).unwrap();
2759 prop_assert_eq!(&vec, &bincode_deserialized);
2760 prop_assert_eq!(vec, schema_deserialized);
2761 }
2762
2763 #[test]
2764 fn test_vec_deque_elem_bytes(vec in proptest::collection::vec_deque(any::<u8>(), 0..=100)) {
2765 let bincode_serialized = bincode::serialize(&vec).unwrap();
2766 let schema_serialized = serialize(&vec).unwrap();
2767 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2768
2769 let bincode_deserialized: VecDeque<u8> = bincode::deserialize(&bincode_serialized).unwrap();
2770 let schema_deserialized: VecDeque<u8> = deserialize(&schema_serialized).unwrap();
2771 prop_assert_eq!(&vec, &bincode_deserialized);
2772 prop_assert_eq!(vec, schema_deserialized);
2773 }
2774
2775 #[test]
2776 fn test_hash_map_zero_copy(map in proptest::collection::hash_map(any::<u8>(), any::<StructZeroCopy>(), 0..=100)) {
2777 let bincode_serialized = bincode::serialize(&map).unwrap();
2778 let schema_serialized = serialize(&map).unwrap();
2779 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2780
2781 let bincode_deserialized = bincode::deserialize(&bincode_serialized).unwrap();
2782 let schema_deserialized = deserialize(&schema_serialized).unwrap();
2783 prop_assert_eq!(&map, &bincode_deserialized);
2784 prop_assert_eq!(map, schema_deserialized);
2785 }
2786
2787 #[test]
2788 fn test_hash_map_static(map in proptest::collection::hash_map(any::<u64>(), any::<StructStatic>(), 0..=100)) {
2789 let bincode_serialized = bincode::serialize(&map).unwrap();
2790 let schema_serialized = serialize(&map).unwrap();
2791 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2792
2793 let bincode_deserialized = bincode::deserialize(&bincode_serialized).unwrap();
2794 let schema_deserialized = deserialize(&schema_serialized).unwrap();
2795 prop_assert_eq!(&map, &bincode_deserialized);
2796 prop_assert_eq!(map, schema_deserialized);
2797 }
2798
2799 #[test]
2800 fn test_hash_map_non_static(map in proptest::collection::hash_map(any::<u64>(), any::<StructNonStatic>(), 0..=16)) {
2801 let bincode_serialized = bincode::serialize(&map).unwrap();
2802 let schema_serialized = serialize(&map).unwrap();
2803 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2804
2805 let bincode_deserialized = bincode::deserialize(&bincode_serialized).unwrap();
2806 let schema_deserialized = deserialize(&schema_serialized).unwrap();
2807 prop_assert_eq!(&map, &bincode_deserialized);
2808 prop_assert_eq!(map, schema_deserialized);
2809 }
2810
2811 #[test]
2812 fn test_hash_set_zero_copy(set in proptest::collection::hash_set(any::<StructZeroCopy>(), 0..=100)) {
2813 let bincode_serialized = bincode::serialize(&set).unwrap();
2814 let schema_serialized = serialize(&set).unwrap();
2815 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2816
2817 let bincode_deserialized = bincode::deserialize(&bincode_serialized).unwrap();
2818 let schema_deserialized = deserialize(&schema_serialized).unwrap();
2819 prop_assert_eq!(&set, &bincode_deserialized);
2820 prop_assert_eq!(set, schema_deserialized);
2821 }
2822
2823 #[test]
2824 fn test_hash_set_static(set in proptest::collection::hash_set(any::<StructStatic>(), 0..=100)) {
2825 let bincode_serialized = bincode::serialize(&set).unwrap();
2826 let schema_serialized = serialize(&set).unwrap();
2827 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2828
2829 let bincode_deserialized = bincode::deserialize(&bincode_serialized).unwrap();
2830 let schema_deserialized = deserialize(&schema_serialized).unwrap();
2831 prop_assert_eq!(&set, &bincode_deserialized);
2832 prop_assert_eq!(set, schema_deserialized);
2833 }
2834
2835 #[test]
2836 fn test_hash_set_non_static(set in proptest::collection::hash_set(any::<StructNonStatic>(), 0..=16)) {
2837 let bincode_serialized = bincode::serialize(&set).unwrap();
2838 let schema_serialized = serialize(&set).unwrap();
2839 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2840
2841 let bincode_deserialized = bincode::deserialize(&bincode_serialized).unwrap();
2842 let schema_deserialized = deserialize(&schema_serialized).unwrap();
2843 prop_assert_eq!(&set, &bincode_deserialized);
2844 prop_assert_eq!(set, schema_deserialized);
2845 }
2846
2847 #[test]
2848 fn test_sequences_with_hasher(data in proptest::collection::hash_map(any::<String>(), any::<HashSet<u32>>(), 0..16)) {
2849 #[derive(Default)]
2850 struct SumHasher(u64);
2851
2852 impl BuildHasher for SumHasher {
2853 type Hasher = Self;
2854 fn build_hasher(&self) -> Self::Hasher {
2855 Self(0)
2856 }
2857 }
2858 impl Hasher for SumHasher {
2859 fn finish(&self) -> u64 {
2860 self.0
2861 }
2862
2863 fn write(&mut self, bytes: &[u8]) {
2864 self.0 += bytes.iter().map(|b| *b as u64).sum::<u64>();
2865 }
2866 }
2867
2868 type TestMap = HashMap<String, HashSet<u32, SumHasher>, SumHasher>;
2869 let test_data: TestMap = data.into_iter().map(|(k, v)| (k, HashSet::from_iter(v.into_iter()))).collect();
2870 let wincode_serialized = serialize(&test_data).unwrap();
2871 let bincode_serialized = bincode::serialize(&test_data).unwrap();
2872 prop_assert_eq!(&wincode_serialized, &bincode_serialized);
2873
2874 let wincode_deserialized: TestMap = deserialize(&wincode_serialized).unwrap();
2875 let bincode_deserialized: TestMap = bincode::deserialize(&bincode_serialized).unwrap();
2876 prop_assert_eq!(&test_data, &wincode_deserialized);
2877 prop_assert_eq!(wincode_deserialized, bincode_deserialized);
2878
2879 type TestMapSeq = containers::FromIntoIterator<TestMap, BincodeLen>;
2880 let test_seq_serialized = TestMapSeq::serialize(&test_data).unwrap();
2881 assert_eq!(test_seq_serialized, wincode_serialized);
2882 let test_seq_deserialized = TestMapSeq::deserialize(&test_seq_serialized).unwrap();
2883 prop_assert_eq!(&test_data, &test_seq_deserialized);
2884
2885 type RegularMap = HashMap<String, HashSet<u32>>;
2886 let regular_deserialized: RegularMap = deserialize(&wincode_serialized).unwrap();
2887 let regular_serialized = serialize(®ular_deserialized).unwrap();
2888 let test_deserialized: TestMap = deserialize(®ular_serialized).unwrap();
2889 prop_assert_eq!(test_data, test_deserialized);
2890
2891 type RegularMapSeq = containers::FromIntoIterator<RegularMap, BincodeLen>;
2892 let regular_seq_serialized = RegularMapSeq::serialize(®ular_deserialized).unwrap();
2893 assert_eq!(regular_serialized, regular_seq_serialized);
2894 let regular_seq_deserialized = RegularMapSeq::deserialize(®ular_seq_serialized).unwrap();
2895 prop_assert_eq!(®ular_deserialized, ®ular_seq_deserialized);
2896 }
2897
2898 #[test]
2899 fn test_btree_map_zero_copy(map in proptest::collection::btree_map(any::<u8>(), any::<StructZeroCopy>(), 0..=100)) {
2900 let bincode_serialized = bincode::serialize(&map).unwrap();
2901 let schema_serialized = serialize(&map).unwrap();
2902 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2903
2904 let bincode_deserialized = bincode::deserialize(&bincode_serialized).unwrap();
2905 let schema_deserialized = deserialize(&schema_serialized).unwrap();
2906 prop_assert_eq!(&map, &bincode_deserialized);
2907 prop_assert_eq!(map, schema_deserialized);
2908 }
2909
2910 #[test]
2911 fn test_btree_map_static(map in proptest::collection::btree_map(any::<u64>(), any::<StructStatic>(), 0..=100)) {
2912 let bincode_serialized = bincode::serialize(&map).unwrap();
2913 let schema_serialized = serialize(&map).unwrap();
2914 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2915
2916 let bincode_deserialized = bincode::deserialize(&bincode_serialized).unwrap();
2917 let schema_deserialized = deserialize(&schema_serialized).unwrap();
2918 prop_assert_eq!(&map, &bincode_deserialized);
2919 prop_assert_eq!(map, schema_deserialized);
2920 }
2921
2922 #[test]
2923 fn test_btree_map_non_static(map in proptest::collection::btree_map(any::<u64>(), any::<StructNonStatic>(), 0..=16)) {
2924 let bincode_serialized = bincode::serialize(&map).unwrap();
2925 let schema_serialized = serialize(&map).unwrap();
2926 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2927
2928 let bincode_deserialized = bincode::deserialize(&bincode_serialized).unwrap();
2929 let schema_deserialized = deserialize(&schema_serialized).unwrap();
2930 prop_assert_eq!(&map, &bincode_deserialized);
2931 prop_assert_eq!(map, schema_deserialized);
2932 }
2933
2934 #[test]
2935 fn test_btree_set_zero_copy(set in proptest::collection::btree_set(any::<StructZeroCopy>(), 0..=100)) {
2936 let bincode_serialized = bincode::serialize(&set).unwrap();
2937 let schema_serialized = serialize(&set).unwrap();
2938 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2939
2940 let bincode_deserialized = bincode::deserialize(&bincode_serialized).unwrap();
2941 let schema_deserialized = deserialize(&schema_serialized).unwrap();
2942 prop_assert_eq!(&set, &bincode_deserialized);
2943 prop_assert_eq!(set, schema_deserialized);
2944 }
2945
2946 #[test]
2947 fn test_btree_set_static(set in proptest::collection::btree_set(any::<StructStatic>(), 0..=100)) {
2948 let bincode_serialized = bincode::serialize(&set).unwrap();
2949 let schema_serialized = serialize(&set).unwrap();
2950 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2951
2952 let bincode_deserialized = bincode::deserialize(&bincode_serialized).unwrap();
2953 let schema_deserialized = deserialize(&schema_serialized).unwrap();
2954 prop_assert_eq!(&set, &bincode_deserialized);
2955 prop_assert_eq!(set, schema_deserialized);
2956 }
2957
2958 #[test]
2959 fn test_btree_set_non_static(map in proptest::collection::btree_set(any::<StructNonStatic>(), 0..=16)) {
2960 let bincode_serialized = bincode::serialize(&map).unwrap();
2961 let schema_serialized = serialize(&map).unwrap();
2962 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2963
2964 let bincode_deserialized = bincode::deserialize(&bincode_serialized).unwrap();
2965 let schema_deserialized = deserialize(&schema_serialized).unwrap();
2966 prop_assert_eq!(&map, &bincode_deserialized);
2967 prop_assert_eq!(map, schema_deserialized);
2968 }
2969
2970 #[test]
2971 fn test_binary_heap_zero_copy(heap in proptest::collection::binary_heap(any::<StructZeroCopy>(), 0..=100)) {
2972 let bincode_serialized = bincode::serialize(&heap).unwrap();
2973 let schema_serialized = serialize(&heap).unwrap();
2974 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2975
2976 let bincode_deserialized: BinaryHeap<StructZeroCopy> = bincode::deserialize(&bincode_serialized).unwrap();
2977 let schema_deserialized: BinaryHeap<StructZeroCopy> = deserialize(&schema_serialized).unwrap();
2978 prop_assert_eq!(heap.as_slice(), bincode_deserialized.as_slice());
2979 prop_assert_eq!(heap.as_slice(), schema_deserialized.as_slice());
2980 }
2981
2982 #[test]
2983 fn test_binary_heap_static(heap in proptest::collection::binary_heap(any::<StructStatic>(), 0..=100)) {
2984 let bincode_serialized = bincode::serialize(&heap).unwrap();
2985 let schema_serialized = serialize(&heap).unwrap();
2986 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2987
2988 let bincode_deserialized: BinaryHeap<StructStatic> = bincode::deserialize(&bincode_serialized).unwrap();
2989 let schema_deserialized: BinaryHeap<StructStatic> = deserialize(&schema_serialized).unwrap();
2990 prop_assert_eq!(heap.as_slice(), bincode_deserialized.as_slice());
2991 prop_assert_eq!(heap.as_slice(), schema_deserialized.as_slice());
2992 }
2993
2994 #[test]
2995 fn test_binary_heap_non_static(heap in proptest::collection::binary_heap(any::<StructNonStatic>(), 0..=16)) {
2996 let bincode_serialized = bincode::serialize(&heap).unwrap();
2997 let schema_serialized = serialize(&heap).unwrap();
2998 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2999
3000 let bincode_deserialized: BinaryHeap<StructNonStatic> = bincode::deserialize(&bincode_serialized).unwrap();
3001 let schema_deserialized: BinaryHeap<StructNonStatic> = deserialize(&schema_serialized).unwrap();
3002 prop_assert_eq!(heap.as_slice(), bincode_deserialized.as_slice());
3003 prop_assert_eq!(heap.as_slice(), schema_deserialized.as_slice());
3004 }
3005
3006 #[test]
3007 fn test_linked_list_zero_copy(list in proptest::collection::linked_list(any::<StructZeroCopy>(), 0..=100)) {
3008 let bincode_serialized = bincode::serialize(&list).unwrap();
3009 let schema_serialized = serialize(&list).unwrap();
3010 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3011
3012 let bincode_deserialized = bincode::deserialize(&bincode_serialized).unwrap();
3013 let schema_deserialized = deserialize(&schema_serialized).unwrap();
3014 prop_assert_eq!(&list, &bincode_deserialized);
3015 prop_assert_eq!(list, schema_deserialized);
3016 }
3017
3018 #[test]
3019 fn test_linked_list_static(list in proptest::collection::linked_list(any::<StructStatic>(), 0..=100)) {
3020 let bincode_serialized = bincode::serialize(&list).unwrap();
3021 let schema_serialized = serialize(&list).unwrap();
3022 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3023
3024 let bincode_deserialized = bincode::deserialize(&bincode_serialized).unwrap();
3025 let schema_deserialized = deserialize(&schema_serialized).unwrap();
3026 prop_assert_eq!(&list, &bincode_deserialized);
3027 prop_assert_eq!(list, schema_deserialized);
3028 }
3029
3030 #[test]
3031 fn test_linked_list_non_static(list in proptest::collection::linked_list(any::<StructNonStatic>(), 0..=16)) {
3032 let bincode_serialized = bincode::serialize(&list).unwrap();
3033 let schema_serialized = serialize(&list).unwrap();
3034 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3035
3036 let bincode_deserialized = bincode::deserialize(&bincode_serialized).unwrap();
3037 let schema_deserialized = deserialize(&schema_serialized).unwrap();
3038 prop_assert_eq!(&list, &bincode_deserialized);
3039 prop_assert_eq!(list, schema_deserialized);
3040 }
3041
3042 #[test]
3043 fn test_array_bytes(array in any::<[u8; 32]>()) {
3044 let bincode_serialized = bincode::serialize(&array).unwrap();
3045 let schema_serialized = serialize(&array).unwrap();
3046 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3047
3048 let bincode_deserialized: [u8; 32] = bincode::deserialize(&bincode_serialized).unwrap();
3049 let schema_deserialized: [u8; 32] = deserialize(&schema_serialized).unwrap();
3050 prop_assert_eq!(&array, &bincode_deserialized);
3051 prop_assert_eq!(array, schema_deserialized);
3052 }
3053
3054 #[test]
3055 fn test_array_static(array in any::<[u64; 32]>()) {
3056 let bincode_serialized = bincode::serialize(&array).unwrap();
3057 type Target = [u64; 32];
3058 let schema_serialized = Target::serialize(&array).unwrap();
3059 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3060 let bincode_deserialized: Target = bincode::deserialize(&bincode_serialized).unwrap();
3061 let schema_deserialized: Target = deserialize(&schema_serialized).unwrap();
3062 prop_assert_eq!(&array, &bincode_deserialized);
3063 prop_assert_eq!(array, schema_deserialized);
3064 }
3065
3066 #[test]
3067 fn test_array_non_static(array in any::<[StructNonStatic; 16]>()) {
3068 let bincode_serialized = bincode::serialize(&array).unwrap();
3069 type Target = [StructNonStatic; 16];
3070 let schema_serialized = Target::serialize(&array).unwrap();
3071 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3072 let bincode_deserialized: Target = bincode::deserialize(&bincode_serialized).unwrap();
3073 let schema_deserialized: Target = deserialize(&schema_serialized).unwrap();
3074 prop_assert_eq!(&array, &bincode_deserialized);
3075 prop_assert_eq!(array, schema_deserialized);
3076 }
3077
3078 #[test]
3079 fn test_option(option in proptest::option::of(any::<StructStatic>())) {
3080 let bincode_serialized = bincode::serialize(&option).unwrap();
3081 let schema_serialized = serialize(&option).unwrap();
3082
3083 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3084 let bincode_deserialized: Option<StructStatic> = bincode::deserialize(&bincode_serialized).unwrap();
3085 let schema_deserialized: Option<StructStatic> = deserialize(&schema_serialized).unwrap();
3086 prop_assert_eq!(&option, &bincode_deserialized);
3087 prop_assert_eq!(&option, &schema_deserialized);
3088 }
3089
3090 #[test]
3091 fn test_option_container(option in proptest::option::of(any::<[u8; 32]>())) {
3092 let bincode_serialized = bincode::serialize(&option).unwrap();
3093 type Target = Option<[u8; 32]>;
3094 let schema_serialized = Target::serialize(&option).unwrap();
3095 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3096 let bincode_deserialized: Option<[u8; 32]> = bincode::deserialize(&bincode_serialized).unwrap();
3097 let schema_deserialized: Option<[u8; 32]> = Target::deserialize(&schema_serialized).unwrap();
3098 prop_assert_eq!(&option, &bincode_deserialized);
3099 prop_assert_eq!(&option, &schema_deserialized);
3100 }
3101
3102 #[test]
3103 fn test_bool(val in any::<bool>()) {
3104 let bincode_serialized = bincode::serialize(&val).unwrap();
3105 let schema_serialized = serialize(&val).unwrap();
3106 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3107 let bincode_deserialized: bool = bincode::deserialize(&bincode_serialized).unwrap();
3108 let schema_deserialized: bool = deserialize(&schema_serialized).unwrap();
3109 prop_assert_eq!(val, bincode_deserialized);
3110 prop_assert_eq!(val, schema_deserialized);
3111 }
3112
3113 #[test]
3114 fn test_bool_invalid_bit_pattern(val in 2u8..=255) {
3115 let bincode_deserialized: Result<bool,_> = bincode::deserialize(&[val]);
3116 let schema_deserialized: Result<bool,_> = deserialize(&[val]);
3117 prop_assert!(bincode_deserialized.is_err());
3118 prop_assert!(schema_deserialized.is_err());
3119 }
3120
3121 #[test]
3122 fn test_box(s in any::<StructStatic>()) {
3123 let data = Box::new(s);
3124 let bincode_serialized = bincode::serialize(&data).unwrap();
3125 let schema_serialized = serialize(&data).unwrap();
3126 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3127
3128 let bincode_deserialized: Box<StructStatic> = bincode::deserialize(&bincode_serialized).unwrap();
3129 let schema_deserialized: Box<StructStatic> = deserialize(&schema_serialized).unwrap();
3130 prop_assert_eq!(&data, &bincode_deserialized);
3131 prop_assert_eq!(&data, &schema_deserialized);
3132 }
3133
3134 #[test]
3135 fn test_rc(s in any::<StructStatic>()) {
3136 let data = Rc::new(s);
3137 let bincode_serialized = bincode::serialize(&data).unwrap();
3138 let schema_serialized = serialize(&data).unwrap();
3139 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3140
3141 let bincode_deserialized: Rc<StructStatic> = bincode::deserialize(&bincode_serialized).unwrap();
3142 let schema_deserialized: Rc<StructStatic> = deserialize(&schema_serialized).unwrap();
3143 prop_assert_eq!(&data, &bincode_deserialized);
3144 prop_assert_eq!(&data, &schema_deserialized);
3145 }
3146
3147 #[test]
3148 fn test_arc(s in any::<StructStatic>()) {
3149 let data = Arc::new(s);
3150 let bincode_serialized = bincode::serialize(&data).unwrap();
3151 let schema_serialized = serialize(&data).unwrap();
3152 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3153
3154 let bincode_deserialized: Arc<StructStatic> = bincode::deserialize(&bincode_serialized).unwrap();
3155 let schema_deserialized: Arc<StructStatic> = deserialize(&schema_serialized).unwrap();
3156 prop_assert_eq!(&data, &bincode_deserialized);
3157 prop_assert_eq!(&data, &schema_deserialized);
3158 }
3159
3160 #[test]
3161 fn test_boxed_slice_zero_copy(vec in proptest::collection::vec(any::<StructZeroCopy>(), 0..=100)) {
3162 let data = vec.into_boxed_slice();
3163 let bincode_serialized = bincode::serialize(&data).unwrap();
3164 let schema_serialized = serialize(&data).unwrap();
3165 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3166
3167 let bincode_deserialized: Box<[StructZeroCopy]> = bincode::deserialize(&bincode_serialized).unwrap();
3168 let schema_deserialized: Box<[StructZeroCopy]> = deserialize(&schema_serialized).unwrap();
3169 prop_assert_eq!(&data, &bincode_deserialized);
3170 prop_assert_eq!(&data, &schema_deserialized);
3171 }
3172
3173 #[test]
3174 fn test_boxed_slice_static(vec in proptest::collection::vec(any::<StructStatic>(), 0..=100)) {
3175 let data = vec.into_boxed_slice();
3176 let bincode_serialized = bincode::serialize(&data).unwrap();
3177 let schema_serialized = serialize(&data).unwrap();
3178 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3179
3180 let bincode_deserialized: Box<[StructStatic]> = bincode::deserialize(&bincode_serialized).unwrap();
3181 let schema_deserialized: Box<[StructStatic]> = deserialize(&schema_serialized).unwrap();
3182 prop_assert_eq!(&data, &bincode_deserialized);
3183 prop_assert_eq!(&data, &schema_deserialized);
3184 }
3185
3186 #[test]
3187 fn test_boxed_slice_non_static(vec in proptest::collection::vec(any::<StructNonStatic>(), 0..=16)) {
3188 let data = vec.into_boxed_slice();
3189 let bincode_serialized = bincode::serialize(&data).unwrap();
3190 type Target = Box<[StructNonStatic]>;
3191 let schema_serialized = serialize(&data).unwrap();
3192 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3193
3194 let bincode_deserialized: Target = bincode::deserialize(&bincode_serialized).unwrap();
3195 let schema_deserialized: Target = Target::deserialize(&schema_serialized).unwrap();
3196 prop_assert_eq!(&data, &bincode_deserialized);
3197 prop_assert_eq!(&data, &schema_deserialized);
3198 }
3199
3200 #[test]
3201 fn test_integers(
3202 val in (
3203 any::<u8>(),
3204 any::<i8>(),
3205 any::<u16>(),
3206 any::<i16>(),
3207 any::<u32>(),
3208 any::<i32>(),
3209 any::<usize>(),
3210 any::<isize>(),
3211 any::<u64>(),
3212 any::<i64>(),
3213 any::<u128>(),
3214 any::<i128>()
3215 )
3216 ) {
3217 type Target = (u8, i8, u16, i16, u32, i32, usize, isize, u64, i64, u128, i128);
3218 let bincode_serialized = bincode::serialize(&val).unwrap();
3219 let schema_serialized = serialize(&val).unwrap();
3220 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3221 let bincode_deserialized: Target = bincode::deserialize(&bincode_serialized).unwrap();
3222 let schema_deserialized: Target = deserialize(&schema_serialized).unwrap();
3223 prop_assert_eq!(val, bincode_deserialized);
3224 prop_assert_eq!(val, schema_deserialized);
3225 }
3226
3227 #[test]
3228 fn test_tuple_zero_copy(
3229 tuple in (
3230 any::<StructZeroCopy>(),
3231 any::<[u8; 32]>(),
3232 )
3233 ) {
3234 let bincode_serialized = bincode::serialize(&tuple).unwrap();
3235 let schema_serialized = serialize(&tuple).unwrap();
3236
3237 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3238 let bincode_deserialized = bincode::deserialize(&bincode_serialized).unwrap();
3239 let schema_deserialized = deserialize(&schema_serialized).unwrap();
3240 prop_assert_eq!(&tuple, &bincode_deserialized);
3241 prop_assert_eq!(&tuple, &schema_deserialized);
3242
3243 }
3244
3245 #[test]
3246 fn test_single_element_tuple(value in any::<u8>()) {
3247 let tuple = (value,);
3248 let bincode_serialized = bincode::serialize(&tuple).unwrap();
3249 let schema_serialized = serialize(&tuple).unwrap();
3250
3251 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3252 let bincode_deserialized: (u8,) = bincode::deserialize(&bincode_serialized).unwrap();
3253 let schema_deserialized: (u8,) = deserialize(&schema_serialized).unwrap();
3254 prop_assert_eq!(tuple, bincode_deserialized);
3255 prop_assert_eq!(tuple, schema_deserialized);
3256 }
3257
3258 #[test]
3259 fn test_tuple_static(
3260 tuple in (
3261 any::<StructStatic>(),
3262 any::<[u8; 32]>(),
3263 )
3264 ) {
3265 let bincode_serialized = bincode::serialize(&tuple).unwrap();
3266 let schema_serialized = serialize(&tuple).unwrap();
3267
3268 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3269 let bincode_deserialized = bincode::deserialize(&bincode_serialized).unwrap();
3270 let schema_deserialized = deserialize(&schema_serialized).unwrap();
3271 prop_assert_eq!(&tuple, &bincode_deserialized);
3272 prop_assert_eq!(&tuple, &schema_deserialized);
3273
3274 }
3275
3276 #[test]
3277 fn test_tuple_non_static(
3278 tuple in (
3279 any::<StructNonStatic>(),
3280 any::<[u8; 32]>(),
3281 proptest::collection::vec(any::<StructStatic>(), 0..=100),
3282 )
3283 ) {
3284 let bincode_serialized = bincode::serialize(&tuple).unwrap();
3285 type BincodeTarget = (StructNonStatic, [u8; 32], Vec<StructStatic>);
3286 type Target = (StructNonStatic, [u8; 32], Vec<StructStatic>);
3287 let schema_serialized = Target::serialize(&tuple).unwrap();
3288
3289 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3290 let bincode_deserialized: BincodeTarget = bincode::deserialize(&bincode_serialized).unwrap();
3291 let schema_deserialized = Target::deserialize(&schema_serialized).unwrap();
3292 prop_assert_eq!(&tuple, &bincode_deserialized);
3293 prop_assert_eq!(&tuple, &schema_deserialized);
3294
3295 }
3296
3297 #[test]
3298 fn test_str(str in any::<String>()) {
3299 let bincode_serialized = bincode::serialize(&str).unwrap();
3300 let schema_serialized = serialize(&str).unwrap();
3301 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3302 let bincode_deserialized: &str = bincode::deserialize(&bincode_serialized).unwrap();
3303 let schema_deserialized: &str = deserialize(&schema_serialized).unwrap();
3304 prop_assert_eq!(&str, &bincode_deserialized);
3305 prop_assert_eq!(&str, &schema_deserialized);
3306
3307 let bincode_deserialized: String = bincode::deserialize(&bincode_serialized).unwrap();
3308 let schema_deserialized: String = deserialize(&schema_serialized).unwrap();
3309 prop_assert_eq!(&str, &bincode_deserialized);
3310 prop_assert_eq!(&str, &schema_deserialized);
3311 }
3312
3313 #[test]
3314 fn test_struct_zero_copy(val in any::<StructZeroCopy>()) {
3315 let bincode_serialized = bincode::serialize(&val).unwrap();
3316 let schema_serialized = serialize(&val).unwrap();
3317 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3318
3319 let bincode_deserialized = bincode::deserialize(&bincode_serialized).unwrap();
3320 let schema_deserialized = deserialize(&schema_serialized).unwrap();
3321 prop_assert_eq!(&val, &bincode_deserialized);
3322 prop_assert_eq!(&val, &schema_deserialized);
3323 }
3324
3325 #[test]
3326 fn test_struct_static(val in any::<StructStatic>()) {
3327 let bincode_serialized = bincode::serialize(&val).unwrap();
3328 let schema_serialized = serialize(&val).unwrap();
3329 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3330
3331 let bincode_deserialized = bincode::deserialize(&bincode_serialized).unwrap();
3332 let schema_deserialized = deserialize(&schema_serialized).unwrap();
3333 prop_assert_eq!(&val, &bincode_deserialized);
3334 prop_assert_eq!(&val, &schema_deserialized);
3335 }
3336
3337 #[test]
3338 fn test_struct_non_static(val in any::<StructNonStatic>()) {
3339 let bincode_serialized = bincode::serialize(&val).unwrap();
3340 let schema_serialized = serialize(&val).unwrap();
3341 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3342
3343 let bincode_deserialized = bincode::deserialize(&bincode_serialized).unwrap();
3344 let schema_deserialized = deserialize(&schema_serialized).unwrap();
3345 prop_assert_eq!(&val, &bincode_deserialized);
3346 prop_assert_eq!(&val, &schema_deserialized);
3347 }
3348
3349 #[test]
3350 fn test_floats(
3351 val in (
3352 any::<f32>(),
3353 any::<f64>(),
3354 )
3355 ) {
3356 let bincode_serialized = bincode::serialize(&val).unwrap();
3357 let schema_serialized = serialize(&val).unwrap();
3358 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3359
3360 let bincode_deserialized: (f32, f64) = bincode::deserialize(&bincode_serialized).unwrap();
3361 let schema_deserialized: (f32, f64) = deserialize(&schema_serialized).unwrap();
3362 prop_assert_eq!(val, bincode_deserialized);
3363 prop_assert_eq!(val, schema_deserialized);
3364 }
3365 }
3366
3367 #[test]
3368 fn test_struct_zero_copy_refs() {
3369 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, Eq, proptest_derive::Arbitrary)]
3371 #[wincode(internal)]
3372 #[repr(C)]
3373 struct Zc {
3374 a: u8,
3375 b: [u8; 64],
3376 c: i8,
3377 d: [i8; 64],
3378 }
3379
3380 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, Eq)]
3382 #[wincode(internal)]
3383 #[repr(C)]
3384 struct ZcRefs<'a> {
3385 a: &'a u8,
3386 b: &'a [u8; 64],
3387 c: &'a i8,
3388 d: &'a [i8; 64],
3389 }
3390
3391 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, Eq)]
3393 #[wincode(internal)]
3394 #[repr(transparent)]
3395 struct ZcWrapper<'a> {
3396 data: &'a Zc,
3397 }
3398
3399 impl<'a> From<&'a ZcRefs<'a>> for Zc {
3400 fn from(value: &'a ZcRefs<'a>) -> Self {
3401 Self {
3402 a: *value.a,
3403 b: *value.b,
3404 c: *value.c,
3405 d: *value.d,
3406 }
3407 }
3408 }
3409
3410 proptest!(proptest_cfg(), |(data in any::<Zc>())| {
3411 let serialized = serialize(&data).unwrap();
3412 let deserialized = Zc::deserialize(&serialized).unwrap();
3413 assert_eq!(data, deserialized);
3414
3415 let serialized_ref = serialize(&ZcRefs { a: &data.a, b: &data.b, c: &data.c, d: &data.d }).unwrap();
3416 assert_eq!(serialized_ref, serialized);
3417 let deserialized_ref = ZcRefs::deserialize(&serialized_ref).unwrap();
3418 assert_eq!(data, (&deserialized_ref).into());
3419
3420 let serialized_wrapper = serialize(&ZcWrapper { data: &data }).unwrap();
3421 assert_eq!(serialized_wrapper, serialized);
3422 let deserialized_wrapper = ZcWrapper::deserialize(&serialized_wrapper).unwrap();
3423 assert_eq!(data, *deserialized_wrapper.data);
3424 });
3425 }
3426
3427 #[test]
3428 fn test_zero_copy_ref_with_integer_types() {
3429 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, Eq)]
3430 #[wincode(internal)]
3431 struct ZcRef<'a> {
3432 x: &'a StructZeroCopy,
3433 }
3434
3435 proptest!(proptest_cfg(), |(data in any::<StructZeroCopy>())| {
3436 let serialized = serialize_aligned(&data).unwrap();
3437 let deserialized: ZcRef<'_> = deserialize(&serialized).unwrap();
3438 assert_eq!(data, *deserialized.x);
3439 });
3440 }
3441
3442 #[test]
3443 fn test_zero_copy_enum_with_integer_types() {
3444 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, Eq, proptest_derive::Arbitrary)]
3445 #[wincode(internal)]
3446 #[wincode(tag_encoding = "u128")]
3447 enum Enum {
3448 A,
3449 B(StructZeroCopy),
3450 }
3451
3452 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, Eq)]
3453 #[wincode(internal)]
3454 #[wincode(tag_encoding = "u128")]
3455 enum EnumRef<'a> {
3456 A,
3457 B(&'a StructZeroCopy),
3458 }
3459
3460 proptest!(proptest_cfg(), |(data in any::<Enum>())| {
3461 let serialized = serialize_aligned(&data).unwrap();
3462 let deserialized: EnumRef<'_> = deserialize(&serialized).unwrap();
3463 match data {
3464 Enum::A => prop_assert!(matches!(deserialized, EnumRef::A)),
3465 Enum::B(x) => prop_assert!(matches!(deserialized, EnumRef::B(y) if &x == y)),
3466 }
3467 });
3468 }
3469
3470 #[test]
3471 fn test_empty_struct() {
3472 #[derive(
3473 Debug,
3474 SchemaWrite,
3475 SchemaRead,
3476 Default,
3477 PartialEq,
3478 Eq,
3479 serde::Serialize,
3480 serde::Deserialize,
3481 )]
3482 #[wincode(internal)]
3483 struct EmptyStruct {}
3484
3485 let empty = EmptyStruct::default();
3486
3487 let bincode_serialized = bincode::serialize(&empty).unwrap();
3488 let schema_serialized = serialize(&empty).unwrap();
3489
3490 assert_eq!(bincode_serialized, schema_serialized);
3492 assert_eq!(bincode_serialized.len(), 0);
3493
3494 let bincode_deserialized: EmptyStruct = bincode::deserialize(&bincode_serialized).unwrap();
3495 let schema_deserialized: EmptyStruct = deserialize(&schema_serialized).unwrap();
3496
3497 assert_eq!(empty, bincode_deserialized);
3498 assert_eq!(empty, schema_deserialized);
3499 }
3500
3501 #[test]
3502 fn test_pod_zero_copy() {
3503 #[derive(Debug, PartialEq, Eq, proptest_derive::Arbitrary, Clone, Copy)]
3504 #[repr(transparent)]
3505 struct Address([u8; 64]);
3506
3507 pod_wrapper! {
3508 unsafe struct PodAddress(Address);
3509 }
3510
3511 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, Eq, proptest_derive::Arbitrary)]
3512 #[wincode(internal)]
3513 #[repr(C)]
3514 struct MyStruct {
3515 #[wincode(with = "PodAddress")]
3516 address: Address,
3517 }
3518
3519 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, Eq)]
3520 #[wincode(internal)]
3521 struct MyStructRef<'a> {
3522 inner: &'a MyStruct,
3523 }
3524
3525 proptest!(proptest_cfg(), |(data in any::<MyStruct>())| {
3526 let serialized = serialize(&data).unwrap();
3527 let deserialized = MyStruct::deserialize(&serialized).unwrap();
3528 assert_eq!(data, deserialized);
3529
3530 let serialized_ref = serialize(&MyStructRef { inner: &data }).unwrap();
3531 assert_eq!(serialized_ref, serialized);
3532 let deserialized_ref = MyStructRef::deserialize(&serialized_ref).unwrap();
3533 assert_eq!(data, *deserialized_ref.inner);
3534 });
3535 }
3536
3537 #[test]
3538 fn test_pod_zero_copy_explicit_ref() {
3539 #[derive(Debug, PartialEq, Eq, proptest_derive::Arbitrary, Clone, Copy)]
3540 #[repr(transparent)]
3541 struct Address([u8; 64]);
3542
3543 pod_wrapper! {
3544 unsafe struct PodAddress(Address);
3545 }
3546
3547 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, Eq)]
3548 #[wincode(internal)]
3549 struct MyStructRef<'a> {
3550 #[wincode(with = "&'a PodAddress")]
3551 address: &'a Address,
3552 }
3553
3554 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, Eq, proptest_derive::Arbitrary)]
3555 #[wincode(internal)]
3556 struct MyStruct {
3557 #[wincode(with = "PodAddress")]
3558 address: Address,
3559 }
3560
3561 proptest!(proptest_cfg(), |(data in any::<MyStruct>())| {
3562 let serialized = serialize(&data).unwrap();
3563 let deserialized = MyStruct::deserialize(&serialized).unwrap();
3564 assert_eq!(data, deserialized);
3565
3566 let serialized_ref = serialize(&MyStructRef { address: &data.address }).unwrap();
3567 assert_eq!(serialized_ref, serialized);
3568 let deserialized_ref = MyStructRef::deserialize(&serialized_ref).unwrap();
3569 assert_eq!(data.address, *deserialized_ref.address);
3570 });
3571 }
3572
3573 #[test]
3574 fn test_read_adapter_lifetime_is_rewritten_to_de() {
3575 #[derive(Debug, PartialEq, Eq)]
3576 struct MyType<'a, T>(&'a [u8; 4], PhantomData<T>);
3577
3578 struct MyOtherType<'a, T>(PhantomData<(&'a (), T)>);
3579
3580 unsafe impl<'de, T, C: Config> SchemaRead<'de, C> for MyOtherType<'de, T> {
3581 type Dst = MyType<'de, T>;
3582
3583 fn read(reader: impl Reader<'de>, dst: &mut MaybeUninit<Self::Dst>) -> ReadResult<()> {
3584 let value = <&'de [u8; 4] as SchemaRead<'de, C>>::get(reader)?;
3585 dst.write(MyType(value, PhantomData));
3586 Ok(())
3587 }
3588 }
3589
3590 #[derive(SchemaRead, Debug, PartialEq, Eq)]
3591 #[wincode(internal)]
3592 struct Foo<'a, T> {
3593 #[wincode(with = "MyOtherType<'a, T>")]
3594 x: MyType<'a, T>,
3595 }
3596
3597 let foo = <Foo<'_, ()> as SchemaRead<'_, DefaultConfig>>::get(&[1, 2, 3, 4][..]).unwrap();
3598 assert_eq!(foo.x, MyType(&[1, 2, 3, 4], PhantomData));
3599 }
3600
3601 #[test]
3602 fn test_result_basic() {
3603 proptest!(proptest_cfg(), |(value: Result<u64, String>)| {
3604 let wincode_serialized = serialize(&value).unwrap();
3605 let bincode_serialized = bincode::serialize(&value).unwrap();
3606 prop_assert_eq!(&wincode_serialized, &bincode_serialized);
3607
3608 let wincode_deserialized: Result<u64, String> = deserialize(&wincode_serialized).unwrap();
3609 let bincode_deserialized: Result<u64, String> = bincode::deserialize(&bincode_serialized).unwrap();
3610 prop_assert_eq!(&value, &wincode_deserialized);
3611 prop_assert_eq!(wincode_deserialized, bincode_deserialized);
3612 });
3613 }
3614
3615 #[test]
3616 fn test_result_bincode_equivalence() {
3617 use serde::{Deserialize, Serialize};
3618
3619 #[derive(
3620 Serialize,
3621 Deserialize,
3622 Debug,
3623 PartialEq,
3624 Clone,
3625 proptest_derive::Arbitrary,
3626 SchemaWrite,
3627 SchemaRead,
3628 )]
3629 #[wincode(internal)]
3630 enum Error {
3631 NotFound,
3632 InvalidInput(String),
3633 Other(u32),
3634 }
3635
3636 proptest!(proptest_cfg(), |(value: Result<Vec<u8>, Error>)| {
3637 let wincode_serialized = serialize(&value).unwrap();
3638 let bincode_serialized = bincode::serialize(&value).unwrap();
3639 prop_assert_eq!(&wincode_serialized, &bincode_serialized);
3640
3641 let wincode_deserialized: Result<Vec<u8>, Error> = deserialize(&wincode_serialized).unwrap();
3642 let bincode_deserialized: Result<Vec<u8>, Error> = bincode::deserialize(&bincode_serialized).unwrap();
3643 prop_assert_eq!(&value, &wincode_deserialized);
3644 prop_assert_eq!(wincode_deserialized, bincode_deserialized);
3645 });
3646 }
3647
3648 #[test]
3649 fn test_result_nested() {
3650 proptest!(proptest_cfg(), |(value: Result<Result<u64, String>, u32>)| {
3651 let wincode_serialized = serialize(&value).unwrap();
3652 let bincode_serialized = bincode::serialize(&value).unwrap();
3653 prop_assert_eq!(&wincode_serialized, &bincode_serialized);
3654
3655 let wincode_deserialized: Result<Result<u64, String>, u32> = deserialize(&wincode_serialized).unwrap();
3656 let bincode_deserialized: Result<Result<u64, String>, u32> = bincode::deserialize(&bincode_serialized).unwrap();
3657 prop_assert_eq!(&value, &wincode_deserialized);
3658 prop_assert_eq!(wincode_deserialized, bincode_deserialized);
3659 });
3660 }
3661
3662 #[test]
3663 fn test_result_with_complex_types() {
3664 use std::collections::HashMap;
3665
3666 proptest!(proptest_cfg(), |(value: Result<HashMap<String, Vec<u32>>, bool>)| {
3667 let wincode_serialized = serialize(&value).unwrap();
3668 let bincode_serialized = bincode::serialize(&value).unwrap();
3669 prop_assert_eq!(&wincode_serialized, &bincode_serialized);
3670
3671 let wincode_deserialized: Result<HashMap<String, Vec<u32>>, bool> = deserialize(&wincode_serialized).unwrap();
3672 let bincode_deserialized: Result<HashMap<String, Vec<u32>>, bool> = bincode::deserialize(&bincode_serialized).unwrap();
3673 prop_assert_eq!(&value, &wincode_deserialized);
3674 prop_assert_eq!(wincode_deserialized, bincode_deserialized);
3675 });
3676 }
3677
3678 #[test]
3679 fn test_result_type_meta_static() {
3680 assert!(matches!(
3682 <Result<u64, u64> as SchemaRead<DefaultConfig>>::TYPE_META,
3683 TypeMeta::Static {
3684 size: 12,
3685 zero_copy: false
3686 }
3687 ));
3688
3689 proptest!(proptest_cfg(), |(value: Result<u64, u64>)| {
3690 let wincode_serialized = serialize(&value).unwrap();
3691 let bincode_serialized = bincode::serialize(&value).unwrap();
3692 prop_assert_eq!(&wincode_serialized, &bincode_serialized);
3693
3694 let wincode_deserialized: Result<u64, u64> = deserialize(&wincode_serialized).unwrap();
3695 let bincode_deserialized: Result<u64, u64> = bincode::deserialize(&bincode_serialized).unwrap();
3696 prop_assert_eq!(&value, &wincode_deserialized);
3697 prop_assert_eq!(wincode_deserialized, bincode_deserialized);
3698 });
3699 }
3700
3701 #[test]
3702 fn test_result_type_meta_dynamic() {
3703 assert!(matches!(
3705 <Result<u64, String> as SchemaRead<DefaultConfig>>::TYPE_META,
3706 TypeMeta::Dynamic
3707 ));
3708
3709 proptest!(proptest_cfg(), |(value: Result<u64, String>)| {
3710 let wincode_serialized = serialize(&value).unwrap();
3711 let bincode_serialized = bincode::serialize(&value).unwrap();
3712 prop_assert_eq!(&wincode_serialized, &bincode_serialized);
3713
3714 let wincode_deserialized: Result<u64, String> = deserialize(&wincode_serialized).unwrap();
3715 let bincode_deserialized: Result<u64, String> = bincode::deserialize(&bincode_serialized).unwrap();
3716 prop_assert_eq!(&value, &wincode_deserialized);
3717 prop_assert_eq!(wincode_deserialized, bincode_deserialized);
3718 });
3719 }
3720
3721 #[test]
3722 fn test_result_type_meta_different_sizes() {
3723 assert!(matches!(
3725 <Result<u64, u32> as SchemaRead<DefaultConfig>>::TYPE_META,
3726 TypeMeta::Dynamic
3727 ));
3728
3729 proptest!(proptest_cfg(), |(value: Result<u64, u32>)| {
3730 let wincode_serialized = serialize(&value).unwrap();
3731 let bincode_serialized = bincode::serialize(&value).unwrap();
3732 prop_assert_eq!(&wincode_serialized, &bincode_serialized);
3733
3734 let wincode_deserialized: Result<u64, u32> = deserialize(&wincode_serialized).unwrap();
3735 let bincode_deserialized: Result<u64, u32> = bincode::deserialize(&bincode_serialized).unwrap();
3736 prop_assert_eq!(&value, &wincode_deserialized);
3737 prop_assert_eq!(wincode_deserialized, bincode_deserialized);
3738 });
3739 }
3740
3741 struct BufAligned {
3747 buf: *mut u8,
3748 layout: Layout,
3749 }
3750
3751 impl Deref for BufAligned {
3752 type Target = [u8];
3753
3754 fn deref(&self) -> &Self::Target {
3755 unsafe { core::slice::from_raw_parts(self.buf as *const u8, self.layout.size()) }
3756 }
3757 }
3758
3759 impl DerefMut for BufAligned {
3760 fn deref_mut(&mut self) -> &mut Self::Target {
3761 unsafe { core::slice::from_raw_parts_mut(self.buf, self.layout.size()) }
3762 }
3763 }
3764
3765 impl Drop for BufAligned {
3766 fn drop(&mut self) {
3767 use alloc::alloc::dealloc;
3768 unsafe { dealloc(self.buf, self.layout) }
3769 }
3770 }
3771
3772 fn serialize_aligned<T>(src: &T) -> WriteResult<BufAligned>
3774 where
3775 T: SchemaWrite<DefaultConfig, Src = T>,
3776 {
3777 use alloc::alloc::alloc;
3778 let size = T::size_of(src)?;
3779 let layout = Layout::from_size_align(size, align_of::<T>()).unwrap();
3780 let mem = unsafe { alloc(layout) };
3781 if mem.is_null() {
3782 return Err(crate::WriteError::Custom("could not allocate"));
3783 }
3784 let mut buf = BufAligned { buf: mem, layout };
3785 crate::serialize_into(buf.deref_mut(), src)?;
3786 Ok(buf)
3787 }
3788
3789 #[test]
3790 fn test_zero_copy_mut_roundrip() {
3791 proptest!(proptest_cfg(), |(data: StructZeroCopy, data_rand: StructZeroCopy)| {
3792 let mut serialized = serialize_aligned(&data).unwrap();
3793 let deserialized: StructZeroCopy = deserialize(&serialized).unwrap();
3794 prop_assert_eq!(deserialized, data);
3795
3796
3797 {
3799 let ref_mut = StructZeroCopy::from_bytes_mut(&mut serialized).unwrap();
3800 *ref_mut = data_rand;
3801 }
3802 let deserialized: StructZeroCopy = deserialize(&serialized).unwrap();
3805 prop_assert_eq!(deserialized, data_rand);
3806 });
3807 }
3808
3809 #[test]
3810 fn test_deserialize_mut_roundrip() {
3811 proptest!(proptest_cfg(), |(data: StructZeroCopy, data_rand: StructZeroCopy)| {
3812 let mut serialized = serialize_aligned(&data).unwrap();
3813 let deserialized: StructZeroCopy = deserialize(&serialized).unwrap();
3814 prop_assert_eq!(deserialized, data);
3815
3816
3817 {
3819 let ref_mut: &mut StructZeroCopy = deserialize_mut(&mut serialized).unwrap();
3820 *ref_mut = data_rand;
3821 }
3822 let deserialized: StructZeroCopy = deserialize(&serialized).unwrap();
3825 prop_assert_eq!(deserialized, data_rand);
3826 });
3827 }
3828
3829 #[test]
3830 fn test_zero_copy_deserialize_ref() {
3831 proptest!(proptest_cfg(), |(data: StructZeroCopy)| {
3832 let serialized = serialize_aligned(&data).unwrap();
3833 let deserialized: StructZeroCopy = deserialize(&serialized).unwrap();
3834 prop_assert_eq!(deserialized, data);
3835
3836 let ref_data = StructZeroCopy::from_bytes(&serialized).unwrap();
3837 prop_assert_eq!(ref_data, &data);
3838 });
3839 }
3840
3841 #[test]
3842 fn test_custom_preallocation_size_limit() {
3843 let c = Configuration::default().with_preallocation_size_limit::<64>();
3844 proptest!(proptest_cfg(), |(value in proptest::collection::vec(any::<u8>(), 0..=128))| {
3845 let wincode_serialized = crate::serialize(&value).unwrap();
3846 let wincode_deserialized: Result<Vec<u8>, _> = config::deserialize(&wincode_serialized, c);
3847 if value.len() <= 64 {
3848 prop_assert_eq!(value, wincode_deserialized.unwrap());
3849 } else {
3850 prop_assert!(wincode_deserialized.is_err());
3851 }
3852 });
3853 }
3854
3855 #[test]
3856 fn test_preallocation_size_limit_rejects_zst_hashmap_len() {
3857 let c = Configuration::default().with_preallocation_size_limit::<4>();
3858 let serialized = 5u64.to_le_bytes();
3859 let decoded: Result<HashMap<(), ()>, _> = config::deserialize(&serialized, c);
3860 assert!(matches!(
3861 decoded,
3862 Err(ReadError::PreallocationSizeLimit {
3863 needed: 5,
3864 limit: 4
3865 })
3866 ));
3867 }
3868
3869 #[test]
3870 fn test_custom_length_encoding() {
3871 let c = Configuration::default().with_length_encoding::<FixIntLen<u32>>();
3872
3873 proptest!(proptest_cfg(), |(value: Vec<u8>)| {
3874 let wincode_serialized = config::serialize(&value, c).unwrap();
3875 let wincode_deserialized: Vec<u8> = config::deserialize(&wincode_serialized, c).unwrap();
3876 let len = value.len();
3877 prop_assert_eq!(len, u32::from_le_bytes(wincode_serialized[0..4].try_into().unwrap()) as usize);
3878 prop_assert_eq!(value, wincode_deserialized);
3879 });
3880 }
3881
3882 #[test]
3883 fn test_duration() {
3884 use core::time::Duration;
3885
3886 proptest!(proptest_cfg(), |(val: Duration)| {
3887 let bincode_serialized = bincode::serialize(&val).unwrap();
3888 let schema_serialized = serialize(&val).unwrap();
3889 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3890
3891 let bincode_deserialized: Duration = bincode::deserialize(&bincode_serialized).unwrap();
3892 let schema_deserialized: Duration = deserialize(&schema_serialized).unwrap();
3893 prop_assert_eq!(val, bincode_deserialized);
3894 prop_assert_eq!(val, schema_deserialized);
3895 });
3896 }
3897
3898 #[test]
3899 fn test_ipv4_addr() {
3900 proptest!(proptest_cfg(), |(addr: Ipv4Addr)| {
3901 let bincode_serialized = bincode::serialize(&addr).unwrap();
3902 let schema_serialized = serialize(&addr).unwrap();
3903 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3904
3905 let bincode_deserialized: Ipv4Addr = bincode::deserialize(&bincode_serialized).unwrap();
3906 let schema_deserialized: Ipv4Addr = deserialize(&schema_serialized).unwrap();
3907 prop_assert_eq!(addr, bincode_deserialized);
3908 prop_assert_eq!(addr, schema_deserialized);
3909 });
3910 }
3911
3912 #[test]
3913 fn test_ipv6_addr() {
3914 proptest!(proptest_cfg(), |(addr: Ipv6Addr)| {
3915 let bincode_serialized = bincode::serialize(&addr).unwrap();
3916 let schema_serialized = serialize(&addr).unwrap();
3917 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3918
3919 let bincode_deserialized: Ipv6Addr = bincode::deserialize(&bincode_serialized).unwrap();
3920 let schema_deserialized: Ipv6Addr = deserialize(&schema_serialized).unwrap();
3921 prop_assert_eq!(addr, bincode_deserialized);
3922 prop_assert_eq!(addr, schema_deserialized);
3923 });
3924 }
3925
3926 #[test]
3927 fn test_ip_addr() {
3928 proptest!(proptest_cfg(), |(addr: IpAddr)| {
3929 let bincode_serialized = bincode::serialize(&addr).unwrap();
3930 let schema_serialized = serialize(&addr).unwrap();
3931 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3932
3933 let bincode_deserialized: IpAddr = bincode::deserialize(&bincode_serialized).unwrap();
3934 let schema_deserialized: IpAddr = deserialize(&schema_serialized).unwrap();
3935 prop_assert_eq!(addr, bincode_deserialized);
3936 prop_assert_eq!(addr, schema_deserialized);
3937 });
3938 }
3939
3940 #[test]
3941 fn test_socket_addr_v4() {
3942 proptest!(proptest_cfg(), |(addr: SocketAddrV4)| {
3943 let bincode_serialized = bincode::serialize(&addr).unwrap();
3944 let schema_serialized = serialize(&addr).unwrap();
3945 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3946
3947 let bincode_deserialized: SocketAddrV4 = bincode::deserialize(&bincode_serialized).unwrap();
3948 let schema_deserialized: SocketAddrV4 = deserialize(&schema_serialized).unwrap();
3949 prop_assert_eq!(addr, bincode_deserialized);
3950 prop_assert_eq!(addr, schema_deserialized);
3951 });
3952 }
3953
3954 #[test]
3955 fn test_socket_addr_v6() {
3956 proptest!(proptest_cfg(), |(addr: SocketAddrV6)| {
3959 let bincode_serialized = bincode::serialize(&addr).unwrap();
3960 let schema_serialized = serialize(&addr).unwrap();
3961 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3962
3963 let bincode_deserialized: SocketAddrV6 = bincode::deserialize(&bincode_serialized).unwrap();
3964 let schema_deserialized: SocketAddrV6 = deserialize(&schema_serialized).unwrap();
3965 prop_assert_eq!(bincode_deserialized, schema_deserialized);
3966 });
3967 }
3968
3969 #[test]
3970 fn test_socket_addr() {
3971 proptest!(proptest_cfg(), |(addr: SocketAddr)| {
3974 let bincode_serialized = bincode::serialize(&addr).unwrap();
3975 let schema_serialized = serialize(&addr).unwrap();
3976 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3977
3978 let bincode_deserialized: SocketAddr = bincode::deserialize(&bincode_serialized).unwrap();
3979 let schema_deserialized: SocketAddr = deserialize(&schema_serialized).unwrap();
3980 prop_assert_eq!(bincode_deserialized, schema_deserialized);
3981 });
3982 }
3983
3984 #[test]
3985 #[cfg(feature = "std")]
3986 fn test_system_time() {
3987 use std::time::{Duration, SystemTime, UNIX_EPOCH};
3988
3989 const MAX_SECS: u64 = i64::MAX as u64 - 1;
3990
3991 proptest!(proptest_cfg(), |(secs in 0u64..=MAX_SECS, nanos in 0u32..1_000_000_000u32)| {
3992 let time = UNIX_EPOCH + Duration::new(secs, nanos);
3993 let bincode_serialized = bincode::serialize(&time).unwrap();
3994 let schema_serialized = serialize(&time).unwrap();
3995 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3996
3997 let bincode_deserialized: SystemTime = bincode::deserialize(&bincode_serialized).unwrap();
3998 let schema_deserialized: SystemTime = deserialize(&schema_serialized).unwrap();
3999 prop_assert_eq!(time, bincode_deserialized);
4000 prop_assert_eq!(time, schema_deserialized);
4001 });
4002 }
4003
4004 #[test]
4005 #[cfg(feature = "std")]
4006 fn test_system_time_before_epoch_errors() {
4007 use std::time::{Duration, UNIX_EPOCH};
4008
4009 let before_epoch = UNIX_EPOCH.checked_sub(Duration::from_secs(1)).unwrap();
4010 assert!(serialize(&before_epoch).is_err());
4011 assert!(crate::serialized_size(&before_epoch).is_err());
4014 }
4015
4016 #[test]
4017 fn test_static_tuple_write_error_leaves_only_initialized_prefix() {
4018 let before_epoch = UNIX_EPOCH.checked_sub(Duration::from_secs(1)).unwrap();
4019 let value = (0xAAu8, before_epoch);
4020 let mut bytes = Vec::new();
4021
4022 assert!(crate::serialize_into(&mut bytes, &value).is_err());
4023 #[cfg(miri)]
4024 if bytes.len() > 1 {
4025 let _ = core::hint::black_box(bytes[1]);
4026 }
4027 assert_eq!(bytes, [0xAA]);
4028 }
4029
4030 #[test]
4031 fn test_deserialize_exact_accepts_exact_input() {
4032 let bytes = serialize(&123u64).unwrap();
4033 let value: u64 = deserialize_exact(&bytes).unwrap();
4034 assert_eq!(value, 123);
4035 }
4036
4037 #[test]
4038 fn test_deserialize_exact_rejects_trailing_bytes() {
4039 let mut bytes = serialize(&123u64).unwrap();
4040 bytes.push(0xAA);
4041 let err = deserialize_exact::<u64>(&bytes).unwrap_err();
4042 assert!(matches!(err, error::ReadError::TrailingBytes));
4043 }
4044
4045 #[test]
4046 fn test_config_deserialize_exact_rejects_trailing_bytes() {
4047 let config = Configuration::default();
4048 let mut bytes = config::serialize(&123u64, config).unwrap();
4049 bytes.push(0xAA);
4050 let err = config::deserialize_exact::<u64, _>(&bytes, config).unwrap_err();
4051 assert!(matches!(err, error::ReadError::TrailingBytes));
4052 }
4053
4054 #[test]
4055 #[cfg(feature = "std")]
4056 fn test_system_time_overflow_errors() {
4057 use {crate::serialize_into, std::time::SystemTime};
4058
4059 let mut bytes = Vec::with_capacity(size_of::<u64>() + size_of::<u32>());
4060 serialize_into(&mut bytes, &u64::MAX).unwrap();
4061 serialize_into(&mut bytes, &0u32).unwrap();
4062
4063 let result: ReadResult<SystemTime> = deserialize(&bytes);
4064 assert!(result.is_err());
4065 }
4066
4067 #[test]
4068 fn test_nonzero_types() {
4069 proptest!(proptest_cfg(), |(
4070 nz_u8: NonZeroU8,
4071 nz_u16: NonZeroU16,
4072 nz_u32: NonZeroU32,
4073 nz_u64: NonZeroU64,
4074 nz_u128: NonZeroU128,
4075 nz_usize: NonZeroUsize,
4076 nz_i8: NonZeroI8,
4077 nz_i16: NonZeroI16,
4078 nz_i32: NonZeroI32,
4079 nz_i64: NonZeroI64,
4080 nz_i128: NonZeroI128,
4081 nz_isize: NonZeroIsize,
4082 )| {
4083 let ser = serialize(&nz_u8).unwrap();
4085 let de: NonZeroU8 = deserialize(&ser).unwrap();
4086 prop_assert_eq!(nz_u8, de);
4087
4088 let ser = serialize(&nz_u16).unwrap();
4089 let de: NonZeroU16 = deserialize(&ser).unwrap();
4090 prop_assert_eq!(nz_u16, de);
4091
4092 let ser = serialize(&nz_u32).unwrap();
4093 let de: NonZeroU32 = deserialize(&ser).unwrap();
4094 prop_assert_eq!(nz_u32, de);
4095
4096 let ser = serialize(&nz_u64).unwrap();
4097 let de: NonZeroU64 = deserialize(&ser).unwrap();
4098 prop_assert_eq!(nz_u64, de);
4099
4100 let ser = serialize(&nz_u128).unwrap();
4101 let de: NonZeroU128 = deserialize(&ser).unwrap();
4102 prop_assert_eq!(nz_u128, de);
4103
4104 let ser = serialize(&nz_usize).unwrap();
4105 let de: NonZeroUsize = deserialize(&ser).unwrap();
4106 prop_assert_eq!(nz_usize, de);
4107
4108 let ser = serialize(&nz_i8).unwrap();
4110 let de: NonZeroI8 = deserialize(&ser).unwrap();
4111 prop_assert_eq!(nz_i8, de);
4112
4113 let ser = serialize(&nz_i16).unwrap();
4114 let de: NonZeroI16 = deserialize(&ser).unwrap();
4115 prop_assert_eq!(nz_i16, de);
4116
4117 let ser = serialize(&nz_i32).unwrap();
4118 let de: NonZeroI32 = deserialize(&ser).unwrap();
4119 prop_assert_eq!(nz_i32, de);
4120
4121 let ser = serialize(&nz_i64).unwrap();
4122 let de: NonZeroI64 = deserialize(&ser).unwrap();
4123 prop_assert_eq!(nz_i64, de);
4124
4125 let ser = serialize(&nz_i128).unwrap();
4126 let de: NonZeroI128 = deserialize(&ser).unwrap();
4127 prop_assert_eq!(nz_i128, de);
4128
4129 let ser = serialize(&nz_isize).unwrap();
4130 let de: NonZeroIsize = deserialize(&ser).unwrap();
4131 prop_assert_eq!(nz_isize, de);
4132 });
4133 }
4134
4135 #[test]
4136 fn test_nonzero_invalid_zero_value() {
4137 let zero_bytes = serialize(&0u32).unwrap();
4139 let result: ReadResult<NonZeroU32> = deserialize(&zero_bytes);
4140 assert!(
4141 result.is_err(),
4142 "Deserializing zero should fail for NonZeroU32"
4143 );
4144
4145 let zero_bytes = serialize(&0u64).unwrap();
4146 let result: ReadResult<NonZeroU64> = deserialize(&zero_bytes);
4147 assert!(
4148 result.is_err(),
4149 "Deserializing zero should fail for NonZeroU64"
4150 );
4151 }
4152
4153 #[test]
4154 fn test_bound_included_u64() {
4155 proptest!(proptest_cfg(), |(value in any::<u64>())| {
4156 let bound = Bound::Included(value);
4157 let serialized = serialize(&bound).unwrap();
4158 let deserialized: Bound<u64> = deserialize(&serialized).unwrap();
4159 prop_assert_eq!(&bound, &deserialized);
4160 });
4161 }
4162
4163 #[test]
4164 fn test_bound_excluded_u64() {
4165 proptest!(proptest_cfg(), |(value in any::<u64>())| {
4166 let bound = Bound::Excluded(value);
4167 let serialized = serialize(&bound).unwrap();
4168 let deserialized: Bound<u64> = deserialize(&serialized).unwrap();
4169 prop_assert_eq!(&bound, &deserialized);
4170 });
4171 }
4172
4173 #[test]
4174 fn test_bound_included_string() {
4175 proptest!(proptest_cfg(), |(value in any::<String>())| {
4176 let bound = Bound::Included(value);
4177 let serialized = serialize(&bound).unwrap();
4178 let deserialized: Bound<String> = deserialize(&serialized).unwrap();
4179 prop_assert_eq!(&bound, &deserialized);
4180 });
4181 }
4182
4183 #[test]
4184 fn test_bound_excluded_string() {
4185 proptest!(proptest_cfg(), |(value in any::<String>())| {
4186 let bound = Bound::Excluded(value);
4187 let serialized = serialize(&bound).unwrap();
4188 let deserialized: Bound<String> = deserialize(&serialized).unwrap();
4189 prop_assert_eq!(&bound, &deserialized);
4190 });
4191 }
4192
4193 #[test]
4194 fn test_bound_included_bincode_equivalence() {
4195 proptest!(proptest_cfg(), |(value in any::<u64>())| {
4196 let bound = Bound::Included(value);
4197 let wincode_serialized = serialize(&bound).unwrap();
4198 let bincode_serialized = bincode::serialize(&bound).unwrap();
4199 prop_assert_eq!(&wincode_serialized, &bincode_serialized);
4200
4201 let wincode_deserialized: Bound<u64> = deserialize(&wincode_serialized).unwrap();
4202 let bincode_deserialized: Bound<u64> = bincode::deserialize(&bincode_serialized).unwrap();
4203 prop_assert_eq!(&bound, &wincode_deserialized);
4204 prop_assert_eq!(&wincode_deserialized, &bincode_deserialized);
4205 });
4206 }
4207
4208 #[test]
4209 fn test_bound_excluded_bincode_equivalence() {
4210 proptest!(proptest_cfg(), |(value in any::<u64>())| {
4211 let bound = Bound::Excluded(value);
4212 let wincode_serialized = serialize(&bound).unwrap();
4213 let bincode_serialized = bincode::serialize(&bound).unwrap();
4214 prop_assert_eq!(&wincode_serialized, &bincode_serialized);
4215
4216 let wincode_deserialized: Bound<u64> = deserialize(&wincode_serialized).unwrap();
4217 let bincode_deserialized: Bound<u64> = bincode::deserialize(&bincode_serialized).unwrap();
4218 prop_assert_eq!(&bound, &wincode_deserialized);
4219 prop_assert_eq!(&wincode_deserialized, &bincode_deserialized);
4220 });
4221 }
4222
4223 #[test]
4224 fn test_range_u64() {
4225 proptest!(proptest_cfg(), |(start in any::<u64>(), end in any::<u64>())| {
4226 let range = Range { start, end };
4227 let serialized = serialize(&range).unwrap();
4228 let deserialized: Range<u64> = deserialize(&serialized).unwrap();
4229 prop_assert_eq!(range.start, deserialized.start);
4230 prop_assert_eq!(range.end, deserialized.end);
4231 });
4232 }
4233
4234 #[test]
4235 fn test_range_string() {
4236 proptest!(proptest_cfg(), |(start in any::<String>(), end in any::<String>())| {
4237 let range = Range { start, end };
4238 let serialized = serialize(&range).unwrap();
4239 let deserialized: Range<String> = deserialize(&serialized).unwrap();
4240 prop_assert_eq!(&range.start, &deserialized.start);
4241 prop_assert_eq!(&range.end, &deserialized.end);
4242 });
4243 }
4244
4245 #[test]
4246 fn test_range_bincode_equivalence() {
4247 proptest!(proptest_cfg(), |(start in any::<u64>(), end in any::<u64>())| {
4248 let range = Range { start, end };
4249 let wincode_serialized = serialize(&range).unwrap();
4250 let bincode_serialized = bincode::serialize(&range).unwrap();
4251 prop_assert_eq!(&wincode_serialized, &bincode_serialized);
4252
4253 let wincode_deserialized: Range<u64> = deserialize(&wincode_serialized).unwrap(); let bincode_deserialized: Range<u64> = bincode::deserialize(&bincode_serialized).unwrap();
4255 prop_assert_eq!(range.start, wincode_deserialized.start);
4256 prop_assert_eq!(range.end, wincode_deserialized.end);
4257 prop_assert_eq!(wincode_deserialized.start, bincode_deserialized.start);
4258 prop_assert_eq!(wincode_deserialized.end, bincode_deserialized.end);
4259 });
4260 }
4261
4262 #[test]
4263 fn test_range_inclusive_u64() {
4264 proptest!(proptest_cfg(), |(start in any::<u64>(), end in any::<u64>())| {
4265 let range = RangeInclusive::new(start, end);
4266 let serialized = serialize(&range).unwrap();
4267 let deserialized: RangeInclusive<u64> = deserialize(&serialized).unwrap();
4268 prop_assert_eq!(range.start(), deserialized.start());
4269 prop_assert_eq!(range.end(), deserialized.end());
4270 });
4271 }
4272
4273 #[test]
4274 fn test_range_inclusive_string() {
4275 proptest!(proptest_cfg(), |(start in any::<String>(), end in any::<String>())| {
4276 let range = RangeInclusive::new(start, end );
4277 let serialized = serialize(&range).unwrap();
4278 let deserialized: RangeInclusive<String> = deserialize(&serialized).unwrap();
4279 prop_assert_eq!(&range.start(), &deserialized.start());
4280 prop_assert_eq!(&range.end(), &deserialized.end());
4281 });
4282 }
4283
4284 #[test]
4285 fn test_range_inclusive_bincode_equivalence() {
4286 proptest!(proptest_cfg(), |(start in any::<u64>(), end in any::<u64>())| {
4287 let range = RangeInclusive::new(start, end );
4288 let wincode_serialized = serialize(&range).unwrap();
4289 let bincode_serialized = bincode::serialize(&range).unwrap();
4290 prop_assert_eq!(&wincode_serialized, &bincode_serialized);
4291
4292 let wincode_deserialized: RangeInclusive<u64> = deserialize(&wincode_serialized).unwrap();
4293 let bincode_deserialized: RangeInclusive<u64> = bincode::deserialize(&bincode_serialized).unwrap();
4294 prop_assert_eq!(range.start(), wincode_deserialized.start());
4295 prop_assert_eq!(range.end(), wincode_deserialized.end());
4296 prop_assert_eq!(wincode_deserialized.start(), bincode_deserialized.start());
4297 prop_assert_eq!(wincode_deserialized.end(), bincode_deserialized.end());
4298 });
4299 }
4300
4301 #[test]
4302 fn test_range_vec_u64() {
4303 proptest!(proptest_cfg(), |(ranges: Vec<Range<u64>>)| {
4304 let serialized = serialize(&ranges).unwrap();
4305 let bincode_serialized = bincode::serialize(&ranges).unwrap();
4306 prop_assert_eq!(&serialized, &bincode_serialized);
4307
4308 let deserialized: Vec<Range<u64>> = deserialize(&serialized).unwrap();
4309 let bincode_deserialized: Vec<Range<u64>> = bincode::deserialize(&bincode_serialized).unwrap();
4310 prop_assert_eq!(deserialized, bincode_deserialized);
4311 });
4312 }
4313
4314 #[test]
4315 fn test_range_inclusive_vec_u64() {
4316 proptest!(proptest_cfg(), |(ranges: Vec<RangeInclusive<u64>>)| {
4317 let serialized = serialize(&ranges).unwrap();
4318 let bincode_serialized = bincode::serialize(&ranges).unwrap();
4319 prop_assert_eq!(&serialized, &bincode_serialized);
4320
4321 let deserialized: Vec<RangeInclusive<u64>> = deserialize(&serialized).unwrap();
4322 let bincode_deserialized: Vec<RangeInclusive<u64>> = bincode::deserialize(&bincode_serialized).unwrap();
4323 prop_assert_eq!(deserialized, bincode_deserialized);
4324 });
4325 }
4326
4327 #[test]
4328 fn test_bound_vec_u64() {
4329 proptest!(proptest_cfg(), |(bounds: Vec<Bound<u64>>)| {
4330 let serialized = serialize(&bounds).unwrap();
4331 let bincode_serialized = bincode::serialize(&bounds).unwrap();
4332 prop_assert_eq!(&serialized, &bincode_serialized);
4333
4334 let deserialized: Vec<Bound<u64>> = deserialize(&serialized).unwrap();
4335 let bincode_deserialized: Vec<Bound<u64>> = bincode::deserialize(&bincode_serialized).unwrap();
4336 prop_assert_eq!(deserialized, bincode_deserialized);
4337 });
4338 }
4339
4340 #[test]
4341 fn test_byte_order_configuration() {
4342 let c = Configuration::default().with_big_endian();
4343 let bincode_c = bincode::DefaultOptions::new()
4344 .with_big_endian()
4345 .with_fixint_encoding();
4346
4347 proptest!(proptest_cfg(), |(value: Vec<u64>)| {
4348 let bincode_serialized = bincode_c.serialize(&value).unwrap();
4349 let serialized = config::serialize(&value, c).unwrap();
4350 prop_assert_eq!(&bincode_serialized, &serialized);
4351
4352 let deserialized: Vec<u64> = config::deserialize(&serialized, c).unwrap();
4353 let len = value.len();
4354 prop_assert_eq!(len, u64::from_be_bytes(serialized[0..8].try_into().unwrap()) as usize);
4355
4356 if !value.is_empty() {
4357 for (i, chunk) in serialized[8..].chunks(8).enumerate() {
4358 let val = u64::from_be_bytes(chunk.try_into().unwrap());
4359 prop_assert_eq!(val, value[i]);
4360 }
4361 }
4362
4363 prop_assert_eq!(value, deserialized);
4364 });
4365 }
4366
4367 #[test]
4368 fn test_duration_nanos_normalization() {
4369 use core::time::Duration;
4370
4371 proptest!(proptest_cfg(), |(secs in 0u64..u64::MAX/2, nanos in 1_000_000_000u32..=u32::MAX)| {
4372 let mut bytes: Vec<u8> = Vec::with_capacity(size_of::<u64>() + size_of::<u32>());
4373 crate::serialize_into(&mut bytes, &secs).unwrap();
4374 crate::serialize_into(&mut bytes, &nanos).unwrap();
4375
4376 let result: Duration = deserialize(&bytes).unwrap();
4377 let expected = Duration::new(secs, nanos);
4378 prop_assert_eq!(result, expected);
4379 });
4380 }
4381
4382 #[test]
4383 fn test_custom_length_encoding_and_byte_order() {
4384 let c = Configuration::default()
4385 .with_length_encoding::<FixIntLen<u32>>()
4386 .with_big_endian();
4387
4388 proptest!(proptest_cfg(), |(value: Vec<u8>)| {
4389 let serialized = config::serialize(&value, c).unwrap();
4390 let deserialized: Vec<u8> = config::deserialize(&serialized, c).unwrap();
4391 let len = value.len();
4392 prop_assert_eq!(len, u32::from_be_bytes(serialized[0..4].try_into().unwrap()) as usize);
4393 prop_assert_eq!(value, deserialized);
4394 });
4395 }
4396
4397 #[test]
4398 fn test_custom_primitive_length_encoding() {
4399 let c = Configuration::default().with_length_encoding::<u32>();
4400
4401 proptest!(proptest_cfg(), |(value: Vec<u8>)| {
4402 let serialized = config::serialize(&value, c).unwrap();
4403 let deserialized: Vec<u8> = config::deserialize(&serialized, c).unwrap();
4404 let len = value.len();
4405 prop_assert_eq!(len, u32::from_le_bytes(serialized[0..4].try_into().unwrap()) as usize);
4406 prop_assert_eq!(value, deserialized);
4407 });
4408 }
4409
4410 #[test]
4411 fn test_duration_overflow() {
4412 use core::time::Duration;
4413
4414 let mut bytes = Vec::with_capacity(size_of::<u64>() + size_of::<u32>());
4415 crate::serialize_into(&mut bytes, &u64::MAX).unwrap();
4416 crate::serialize_into(&mut bytes, &1_000_000_000u32).unwrap();
4417
4418 let result: error::ReadResult<Duration> = deserialize(&bytes);
4419 assert!(result.is_err());
4420 }
4421
4422 #[test]
4423 fn test_all_integers_with_custom_byte_order() {
4424 let c = Configuration::default().with_big_endian();
4425 let bincode_c = bincode::DefaultOptions::new()
4426 .with_big_endian()
4427 .with_fixint_encoding();
4428
4429 proptest!(proptest_cfg(), |(value: (u16, u32, u64, u128, i16, i32, i64, i128, usize, isize))| {
4430 let bincode_serialized = bincode_c.serialize(&value).unwrap();
4431 let serialized = config::serialize(&value, c).unwrap();
4432 prop_assert_eq!(&bincode_serialized, &serialized);
4433 let deserialized: (u16, u32, u64, u128, i16, i32, i64, i128, usize, isize) = config::deserialize(&serialized, c).unwrap();
4434 prop_assert_eq!(value, deserialized);
4435 });
4436 }
4437
4438 #[test]
4439 fn test_all_integers_with_varint() {
4440 let c = Configuration::default().with_varint_encoding();
4441 let bincode_c = bincode::DefaultOptions::new().with_varint_encoding();
4442
4443 proptest!(proptest_cfg(), |(value: (u16, u32, u64, u128, i16, i32, i64, i128, usize, isize))| {
4444 let bincode_serialized = bincode_c.serialize(&value).unwrap();
4445 let serialized = config::serialize(&value, c).unwrap();
4446 prop_assert_eq!(&bincode_serialized, &serialized);
4447 prop_assert_eq!(bincode_c.serialized_size(&value).unwrap(), config::serialized_size(&value, c).unwrap());
4448
4449 let deserialized: (u16, u32, u64, u128, i16, i32, i64, i128, usize, isize) = config::deserialize(&serialized, c).unwrap();
4450 prop_assert_eq!(value, deserialized);
4451 });
4452 }
4453
4454 #[test]
4455 fn test_all_integers_with_varint_big_endian() {
4456 let c = Configuration::default()
4457 .with_varint_encoding()
4458 .with_big_endian();
4459 let bincode_c = bincode::DefaultOptions::new()
4460 .with_varint_encoding()
4461 .with_big_endian();
4462
4463 proptest!(proptest_cfg(), |(value: (u16, u32, u64, u128, i16, i32, i64, i128, usize, isize))| {
4464 let bincode_serialized = bincode_c.serialize(&value).unwrap();
4465 let serialized = config::serialize(&value, c).unwrap();
4466 prop_assert_eq!(&bincode_serialized, &serialized);
4467 prop_assert_eq!(bincode_c.serialized_size(&value).unwrap(), config::serialized_size(&value, c).unwrap());
4468
4469 let deserialized: (u16, u32, u64, u128, i16, i32, i64, i128, usize, isize) = config::deserialize(&serialized, c).unwrap();
4470 prop_assert_eq!(value, deserialized);
4471 });
4472 }
4473
4474 #[test]
4475 fn test_varint_boundaries() {
4476 let c = Configuration::default().with_varint_encoding();
4477 let bincode_c = bincode::DefaultOptions::new().with_varint_encoding();
4478
4479 fn assert_varint_roundtrip<T, C, O>(val: T, c: C, bincode_c: O)
4480 where
4481 C: Config + Copy,
4482 O: Options + Copy,
4483 T: serde::Serialize
4484 + for<'de> Deserialize<'de>
4485 + PartialEq
4486 + core::fmt::Debug
4487 + SchemaWrite<C, Src = T>
4488 + for<'de> SchemaRead<'de, C, Dst = T>,
4489 {
4490 let bincode_serialized = bincode_c.serialize(&val).unwrap();
4491 let serialized = config::serialize(&val, c).unwrap();
4492 assert_eq!(bincode_serialized, serialized);
4493 assert_eq!(
4494 bincode_c.serialized_size(&val).unwrap(),
4495 config::serialized_size(&val, c).unwrap()
4496 );
4497 let deserialized: T = config::deserialize(&serialized, c).unwrap();
4498 assert_eq!(val, deserialized);
4499 }
4500
4501 for val in [0u16, 1, 250, 251, 252, u16::MAX] {
4502 assert_varint_roundtrip(val, c, bincode_c);
4503 }
4504
4505 for val in [
4506 0u32,
4507 1,
4508 250,
4509 251,
4510 252,
4511 u16::MAX as u32,
4512 u16::MAX as u32 + 1,
4513 u32::MAX,
4514 ] {
4515 assert_varint_roundtrip(val, c, bincode_c);
4516 }
4517
4518 for val in [
4519 0u64,
4520 1,
4521 250,
4522 251,
4523 252,
4524 u16::MAX as u64,
4525 u16::MAX as u64 + 1,
4526 u32::MAX as u64,
4527 u32::MAX as u64 + 1,
4528 u64::MAX,
4529 ] {
4530 assert_varint_roundtrip(val, c, bincode_c);
4531 }
4532
4533 for val in [
4534 0u128,
4535 1,
4536 250,
4537 251,
4538 252,
4539 u16::MAX as u128,
4540 u16::MAX as u128 + 1,
4541 u32::MAX as u128,
4542 u32::MAX as u128 + 1,
4543 u64::MAX as u128,
4544 u64::MAX as u128 + 1,
4545 u128::MAX,
4546 ] {
4547 assert_varint_roundtrip(val, c, bincode_c);
4548 }
4549
4550 for val in [0i16, 1, -1, 2, -2, i16::MIN, i16::MAX] {
4551 assert_varint_roundtrip(val, c, bincode_c);
4552 }
4553
4554 for val in [0i32, 1, -1, 2, -2, i32::MIN, i32::MAX] {
4555 assert_varint_roundtrip(val, c, bincode_c);
4556 }
4557
4558 for val in [0i64, 1, -1, 2, -2, i64::MIN, i64::MAX] {
4559 assert_varint_roundtrip(val, c, bincode_c);
4560 }
4561
4562 for val in [0i128, 1, -1, 2, -2, i128::MIN, i128::MAX] {
4563 assert_varint_roundtrip(val, c, bincode_c);
4564 }
4565 }
4566
4567 #[test]
4568 fn test_floats_with_custom_byte_order() {
4569 let c = Configuration::default().with_big_endian();
4570 let bincode_c = bincode::DefaultOptions::new()
4571 .with_big_endian()
4572 .with_fixint_encoding();
4573
4574 proptest!(proptest_cfg(), |(value: (f32, f64))| {
4575 let bincode_serialized = bincode_c.serialize(&value).unwrap();
4576 let serialized = config::serialize(&value, c).unwrap();
4577 prop_assert_eq!(&bincode_serialized, &serialized);
4578 let deserialized: (f32, f64) = config::deserialize(&serialized, c).unwrap();
4579 prop_assert_eq!(value, deserialized);
4580 });
4581 }
4582
4583 #[test]
4584 fn test_generic_struct() {
4585 #[derive(
4586 SchemaWrite,
4587 SchemaRead,
4588 serde::Serialize,
4589 serde::Deserialize,
4590 Debug,
4591 PartialEq,
4592 Eq,
4593 proptest_derive::Arbitrary,
4594 )]
4595 #[wincode(internal)]
4596 struct GenT<T> {
4597 inner: T,
4598 }
4599
4600 assert_eq!(
4601 <GenT<u64> as SchemaWrite<DefaultConfig>>::TYPE_META,
4602 TypeMeta::Static {
4603 size: 8,
4604 zero_copy: false
4605 }
4606 );
4607
4608 assert_eq!(
4609 <GenT<String> as SchemaWrite<DefaultConfig>>::TYPE_META,
4610 TypeMeta::Dynamic,
4611 );
4612
4613 proptest!(proptest_cfg(), |(value: GenT<u64>)| {
4614 let serialized = serialize(&value).unwrap();
4615 let bincode_serialized = bincode::serialize(&value).unwrap();
4616 prop_assert_eq!(&serialized, &bincode_serialized);
4617 let deserialized: GenT<u64> = deserialize(&serialized).unwrap();
4618 let bincode_deserialized: GenT<u64> = bincode::deserialize(&bincode_serialized).unwrap();
4619 prop_assert_eq!(&deserialized, &bincode_deserialized);
4620 prop_assert_eq!(value, deserialized);
4621 });
4622 }
4623
4624 #[test]
4625 fn test_generic_struct_two_params() {
4626 #[derive(
4627 SchemaWrite,
4628 SchemaRead,
4629 serde::Serialize,
4630 serde::Deserialize,
4631 Debug,
4632 PartialEq,
4633 Eq,
4634 proptest_derive::Arbitrary,
4635 )]
4636 #[wincode(internal)]
4637 struct GenT<T, U> {
4638 t: T,
4639 u: U,
4640 }
4641
4642 assert_eq!(
4643 <GenT<u64, u64> as SchemaWrite<DefaultConfig>>::TYPE_META,
4644 TypeMeta::Static {
4645 size: 16,
4646 zero_copy: false
4647 }
4648 );
4649
4650 assert_eq!(
4651 <GenT<String, u64> as SchemaWrite<DefaultConfig>>::TYPE_META,
4652 TypeMeta::Dynamic,
4653 );
4654
4655 proptest!(proptest_cfg(), |(value: GenT<u64, u64>)| {
4656 let serialized = serialize(&value).unwrap();
4657 let bincode_serialized = bincode::serialize(&value).unwrap();
4658 prop_assert_eq!(&serialized, &bincode_serialized);
4659 let deserialized: GenT<u64, u64> = deserialize(&serialized).unwrap();
4660 let bincode_deserialized: GenT<u64, u64> = bincode::deserialize(&bincode_serialized).unwrap();
4661 prop_assert_eq!(&deserialized, &bincode_deserialized);
4662 prop_assert_eq!(value, deserialized);
4663 });
4664 }
4665
4666 #[test]
4667 fn test_generic_struct_repr_transparent() {
4668 #[derive(
4669 SchemaWrite,
4670 SchemaRead,
4671 serde::Serialize,
4672 serde::Deserialize,
4673 Debug,
4674 PartialEq,
4675 Eq,
4676 proptest_derive::Arbitrary,
4677 )]
4678 #[wincode(internal)]
4679 #[repr(transparent)]
4680 struct GenT<T> {
4681 inner: T,
4682 }
4683
4684 assert_eq!(
4685 <GenT<u64> as SchemaWrite<DefaultConfig>>::TYPE_META,
4686 TypeMeta::Static {
4687 size: 8,
4688 zero_copy: true
4689 }
4690 );
4691
4692 proptest!(proptest_cfg(), |(value: GenT<u64>)| {
4693 let serialized = serialize(&value).unwrap();
4694 let bincode_serialized = bincode::serialize(&value).unwrap();
4695 prop_assert_eq!(&serialized, &bincode_serialized);
4696 let deserialized: GenT<u64> = deserialize(&serialized).unwrap();
4697 let bincode_deserialized: GenT<u64> = bincode::deserialize(&bincode_serialized).unwrap();
4698 prop_assert_eq!(&deserialized, &bincode_deserialized);
4699 prop_assert_eq!(value, deserialized);
4700 });
4701 }
4702
4703 #[test]
4704 fn test_generic_struct_with_existing_bound() {
4705 #[derive(
4706 SchemaWrite,
4707 SchemaRead,
4708 serde::Serialize,
4709 serde::Deserialize,
4710 Debug,
4711 PartialEq,
4712 Eq,
4713 proptest_derive::Arbitrary,
4714 )]
4715 #[wincode(internal)]
4716 #[repr(transparent)]
4717 struct GenT<T: Copy> {
4718 inner: T,
4719 }
4720
4721 proptest!(proptest_cfg(), |(value: GenT<u64>)| {
4722 let serialized = serialize(&value).unwrap();
4723 let bincode_serialized = bincode::serialize(&value).unwrap();
4724 prop_assert_eq!(&serialized, &bincode_serialized);
4725 let deserialized: GenT<u64> = deserialize(&serialized).unwrap();
4726 let bincode_deserialized: GenT<u64> = bincode::deserialize(&bincode_serialized).unwrap();
4727 prop_assert_eq!(&deserialized, &bincode_deserialized);
4728 prop_assert_eq!(value, deserialized);
4729 });
4730 }
4731
4732 #[test]
4733 fn test_generic_enum() {
4734 #[derive(
4735 SchemaWrite,
4736 SchemaRead,
4737 serde::Serialize,
4738 serde::Deserialize,
4739 Debug,
4740 PartialEq,
4741 Eq,
4742 proptest_derive::Arbitrary,
4743 )]
4744 #[wincode(internal)]
4745 enum GenT<T> {
4746 A(T),
4747 B(u8),
4748 }
4749
4750 assert_eq!(
4751 <GenT<u8> as SchemaWrite<DefaultConfig>>::TYPE_META,
4752 TypeMeta::Static {
4753 size: size_of::<u32>() + 1,
4754 zero_copy: false
4755 }
4756 );
4757
4758 assert_eq!(
4759 <GenT<u64> as SchemaWrite<DefaultConfig>>::TYPE_META,
4760 TypeMeta::Dynamic,
4761 );
4762
4763 proptest!(proptest_cfg(), |(value: GenT<u64>)| {
4764 let serialized = serialize(&value).unwrap();
4765 let bincode_serialized = bincode::serialize(&value).unwrap();
4766 prop_assert_eq!(&serialized, &bincode_serialized);
4767 let deserialized: GenT<u64> = deserialize(&serialized).unwrap();
4768 let bincode_deserialized: GenT<u64> = bincode::deserialize(&bincode_serialized).unwrap();
4769 prop_assert_eq!(&deserialized, &bincode_deserialized);
4770 prop_assert_eq!(value, deserialized);
4771 });
4772 }
4773
4774 #[test]
4775 fn test_recursive_type() {
4776 #[derive(
4777 SchemaWrite, SchemaRead, PartialEq, Debug, serde::Serialize, serde::Deserialize,
4778 )]
4779 #[wincode(internal)]
4780 pub enum Value {
4781 Usize(usize),
4782 List(Vec<Value>),
4783 }
4784
4785 let val = Value::List(vec![Value::Usize(0), Value::List(vec![Value::Usize(1)])]);
4786 let bincode_serialized = bincode::serialize(&val).unwrap();
4787 let serialized = serialize(&val).unwrap();
4788 assert_eq!(&bincode_serialized, &serialized);
4789
4790 let deserialized: Value = deserialize(&serialized).unwrap();
4791 let bincode_deserialized: Value = bincode::deserialize(&bincode_serialized).unwrap();
4792 assert_eq!(&val, &bincode_deserialized);
4793 assert_eq!(val, deserialized);
4794 }
4795
4796 #[test]
4797 fn test_cow_str() {
4798 proptest!(proptest_cfg(), |(value: Cow<str>)| {
4799 let serialized = serialize(&value).unwrap();
4800 let bincode_serialized = bincode::serialize(&value).unwrap();
4801 prop_assert_eq!(&serialized, &bincode_serialized);
4802 let deserialized: Cow<str> = deserialize(&serialized).unwrap();
4803 let bincode_deserialized: Cow<str> = bincode::deserialize(&bincode_serialized).unwrap();
4804 prop_assert_eq!(&deserialized, &bincode_deserialized);
4805 prop_assert_eq!(value, deserialized);
4806 });
4807 }
4808
4809 #[test]
4810 fn test_cow_bytes() {
4811 proptest!(proptest_cfg(), |(value: Cow<[u8]>)| {
4812 let serialized = serialize(&value).unwrap();
4813 let bincode_serialized = bincode::serialize(&value).unwrap();
4814 prop_assert_eq!(&serialized, &bincode_serialized);
4815 let deserialized: Cow<[u8]> = deserialize(&serialized).unwrap();
4816 let bincode_deserialized: Cow<[u8]> = bincode::deserialize(&bincode_serialized).unwrap();
4817 prop_assert_eq!(&deserialized, &bincode_deserialized);
4818 prop_assert_eq!(value, deserialized);
4819 });
4820 }
4821
4822 #[test]
4823 fn test_cow_bytes_owned() {
4824 proptest!(proptest_cfg(), |(value: Cow<[u8]>)| {
4825 let serialized = serialize(&value).unwrap();
4826 let bincode_serialized = bincode::serialize(&value).unwrap();
4827 prop_assert_eq!(&serialized, &bincode_serialized);
4828 let deserialized = <Cow<[u8]> as SchemaRead<DefaultConfig>>
4829 ::get(NoBorrowReader::new(&serialized)).unwrap();
4830 let bincode_deserialized: Cow<[u8]> = bincode::deserialize_from(bincode_serialized.as_slice()).unwrap();
4831 prop_assert_eq!(&deserialized, &bincode_deserialized);
4832 prop_assert_eq!(value, deserialized);
4833 });
4834 }
4835
4836 #[test]
4837 fn test_cow_str_owned() {
4838 proptest!(proptest_cfg(), |(value: Cow<str>)| {
4839 let serialized = serialize(&value).unwrap();
4840 let bincode_serialized = bincode::serialize(&value).unwrap();
4841 prop_assert_eq!(&serialized, &bincode_serialized);
4842 let deserialized = <Cow<str> as SchemaRead<DefaultConfig>>
4843 ::get(NoBorrowReader::new(&serialized)).unwrap();
4844 let bincode_deserialized: Cow<str> = bincode::deserialize_from(bincode_serialized.as_slice()).unwrap();
4845 prop_assert_eq!(&deserialized, &bincode_deserialized);
4846 prop_assert_eq!(value, deserialized);
4847 });
4848 }
4849
4850 #[test]
4851 fn test_cow_ctx() {
4852 #[derive(Debug, PartialEq)]
4853 struct MaybeBorrowed<'a> {
4854 len: u8,
4855 data: Cow<'a, [u8]>,
4856 }
4857
4858 unsafe impl<'a, C: ConfigCore> SchemaWrite<C> for MaybeBorrowed<'a> {
4859 type Src = Self;
4860
4861 fn size_of(src: &Self::Src) -> WriteResult<usize> {
4862 Ok(1 + src.data.len())
4863 }
4864
4865 fn write(mut writer: impl Writer, src: &Self::Src) -> WriteResult<()> {
4866 writer.write(&[src.data.len() as u8])?;
4867 writer.write(&src.data)?;
4868 Ok(())
4869 }
4870 }
4871
4872 unsafe impl<'de, C: ConfigCore> SchemaRead<'de, C> for MaybeBorrowed<'de> {
4873 type Dst = Self;
4874
4875 fn read(
4876 mut reader: impl Reader<'de>,
4877 dst: &mut MaybeUninit<Self::Dst>,
4878 ) -> ReadResult<()> {
4879 let len = reader.take_byte()?;
4880 let cow = <Cow<'de, [u8]> as SchemaReadContext<C, _>>::get_with_context(
4881 context::Len(len as usize),
4882 reader,
4883 )?;
4884 dst.write(MaybeBorrowed { len, data: cow });
4885 Ok(())
4886 }
4887 }
4888
4889 proptest!(proptest_cfg(), |(value in proptest::collection::vec(any::<u8>(), 0..=64))| {
4890 let value = MaybeBorrowed {
4891 len: value.len() as u8,
4892 data: Cow::Owned(value),
4893 };
4894
4895 let serialized = serialize(&value).unwrap();
4896
4897 let deserialized = <MaybeBorrowed as SchemaRead<DefaultConfig>>
4898 ::get(NoBorrowReader::new(&serialized)).unwrap();
4899 prop_assert!(matches!(deserialized.data, Cow::Owned(_)));
4900 prop_assert_eq!(&value, &deserialized);
4901
4902 let deserialized: MaybeBorrowed = deserialize(&serialized).unwrap();
4903 prop_assert!(matches!(deserialized.data, Cow::Borrowed(_)));
4904 prop_assert_eq!(value, deserialized);
4905 });
4906 }
4907
4908 #[test]
4909 fn test_external_wincode() {
4910 use crate as my_wincode;
4911 #[derive(SchemaRead, SchemaWrite, Debug, PartialEq)]
4912 #[wincode(crate = "my_wincode")]
4913 struct Foo {
4914 bar: u8,
4915 }
4916
4917 let data = Foo { bar: 42 };
4918 let serialized = serialize(&data).unwrap();
4919 let deserialized: Foo = deserialize(&serialized).unwrap();
4920 assert_eq!(data, deserialized);
4921 }
4922
4923 #[test]
4924 fn test_mutex_roundtrip() {
4925 let value = Mutex::new(0x0123_4567_89ab_cdef_u64);
4926 let serialized = serialize(&value).unwrap();
4927 let deserialized: Mutex<u64> = deserialize(&serialized).unwrap();
4928
4929 assert_eq!(*value.lock().unwrap(), *deserialized.lock().unwrap());
4930 assert_eq!(
4931 <Mutex<u64> as SchemaWrite<DefaultConfig>>::TYPE_META,
4932 TypeMeta::Static {
4933 size: size_of::<u64>(),
4934 zero_copy: false
4935 }
4936 );
4937 assert_eq!(
4938 <Mutex<u64> as SchemaRead<'_, DefaultConfig>>::TYPE_META,
4939 TypeMeta::Static {
4940 size: size_of::<u64>(),
4941 zero_copy: false
4942 }
4943 );
4944 }
4945
4946 #[test]
4947 fn test_mutex_write_errors_when_poisoned() {
4948 let value = Mutex::new(123_u32);
4949
4950 let _ = std::panic::catch_unwind(|| {
4951 let _guard = value.lock().unwrap();
4952 panic!("poison mutex for serialization test");
4953 });
4954
4955 assert!(value.is_poisoned());
4956 assert!(<Mutex<u32> as SchemaWrite<DefaultConfig>>::size_of(&value).is_err());
4957
4958 let mut bytes = Vec::new();
4959 assert!(<Mutex<u32> as SchemaWrite<DefaultConfig>>::write(&mut bytes, &value).is_err());
4960 assert!(serialize(&value).is_err());
4961 }
4962
4963 #[test]
4964 fn test_mutex_unsized_slice_write() {
4965 let value = Mutex::new([1_u8, 2, 3, 4]);
4966 let value: &Mutex<[u8]> = &value;
4967
4968 let serialized = <Mutex<[u8]> as Serialize>::serialize(value).unwrap();
4969 let expected = serialize(&[1_u8, 2, 3, 4][..]).unwrap();
4970
4971 assert_eq!(serialized, expected);
4972 }
4973
4974 #[test]
4975 fn test_rwlock_roundtrip() {
4976 let value = RwLock::new(0x0123_4567_89ab_cdef_u64);
4977 let serialized = serialize(&value).unwrap();
4978 let deserialized: RwLock<u64> = deserialize(&serialized).unwrap();
4979
4980 assert_eq!(*value.read().unwrap(), *deserialized.read().unwrap());
4981 assert_eq!(
4982 <RwLock<u64> as SchemaWrite<DefaultConfig>>::TYPE_META,
4983 TypeMeta::Static {
4984 size: size_of::<u64>(),
4985 zero_copy: false
4986 }
4987 );
4988 assert_eq!(
4989 <RwLock<u64> as SchemaRead<'_, DefaultConfig>>::TYPE_META,
4990 TypeMeta::Static {
4991 size: size_of::<u64>(),
4992 zero_copy: false
4993 }
4994 );
4995 }
4996
4997 #[test]
4998 fn test_rwlock_write_errors_when_poisoned() {
4999 let value = RwLock::new(123_u32);
5000
5001 let _ = std::panic::catch_unwind(|| {
5002 let _guard = value.write().unwrap();
5003 panic!("poison rwlock for serialization test");
5004 });
5005
5006 assert!(value.is_poisoned());
5007 assert!(<RwLock<u32> as SchemaWrite<DefaultConfig>>::size_of(&value).is_err());
5008
5009 let mut bytes = Vec::new();
5010 assert!(<RwLock<u32> as SchemaWrite<DefaultConfig>>::write(&mut bytes, &value).is_err());
5011 assert!(serialize(&value).is_err());
5012 }
5013
5014 #[test]
5015 fn test_rwlock_unsized_slice_write() {
5016 let value = RwLock::new([1_u8, 2, 3, 4]);
5017 let value: &RwLock<[u8]> = &value;
5018
5019 let serialized = <RwLock<[u8]> as Serialize>::serialize(value).unwrap();
5020 let expected = serialize(&[1_u8, 2, 3, 4][..]).unwrap();
5021
5022 assert_eq!(serialized, expected);
5023 }
5024
5025 #[test]
5027 fn test_generic_associated_type_only() {
5028 trait HasAssoc {
5029 type Value: for<'de> SchemaRead<'de, DefaultConfig, Dst = Self::Value>
5030 + SchemaWrite<DefaultConfig, Src = Self::Value>
5031 + Clone
5032 + core::fmt::Debug
5033 + PartialEq;
5034 }
5035
5036 #[derive(Debug, PartialEq)]
5037 struct UsesU64;
5038 impl HasAssoc for UsesU64 {
5039 type Value = u64;
5040 }
5041
5042 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, Clone)]
5043 #[wincode(internal)]
5044 struct Wrapper<T: HasAssoc> {
5045 inner: T::Value,
5046 }
5047
5048 let original = Wrapper::<UsesU64> { inner: 42u64 };
5049 let serialized = serialize(&original).unwrap();
5050 let deserialized: Wrapper<UsesU64> = deserialize(&serialized).unwrap();
5051 assert_eq!(original, deserialized);
5052 }
5053
5054 #[test]
5056 fn test_generic_direct_type() {
5057 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, Clone)]
5058 #[wincode(internal)]
5059 struct Wrapper<T> {
5060 inner: T,
5061 }
5062
5063 let original = Wrapper::<String> {
5064 inner: "hello".into(),
5065 };
5066 let serialized = serialize(&original).unwrap();
5067 let deserialized: Wrapper<String> = deserialize(&serialized).unwrap();
5068 assert_eq!(original, deserialized);
5069 }
5070
5071 #[test]
5073 fn test_generic_direct_and_associated_type() {
5074 trait HasAssoc {
5075 type Extra: for<'de> SchemaRead<'de, DefaultConfig, Dst = Self::Extra>
5076 + SchemaWrite<DefaultConfig, Src = Self::Extra>
5077 + Clone
5078 + core::fmt::Debug
5079 + PartialEq;
5080 }
5081
5082 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, Clone)]
5083 #[wincode(internal)]
5084 struct Both<T: HasAssoc> {
5085 direct: T,
5086 assoc: T::Extra,
5087 }
5088
5089 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, Clone)]
5090 #[wincode(internal)]
5091 struct MyData {
5092 value: u32,
5093 }
5094
5095 impl HasAssoc for MyData {
5096 type Extra = String;
5097 }
5098
5099 let original = Both::<MyData> {
5100 direct: MyData { value: 42 },
5101 assoc: "hello".into(),
5102 };
5103 let serialized = serialize(&original).unwrap();
5104 let deserialized: Both<MyData> = deserialize(&serialized).unwrap();
5105 assert_eq!(original, deserialized);
5106 }
5107
5108 #[test]
5109 fn test_generic_type_with_container_adapter() {
5110 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, Clone)]
5111 #[wincode(internal)]
5112 struct Wrapper<T> {
5113 #[wincode(with = "containers::Vec<_, BincodeLen>")]
5114 inner: Vec<T>,
5115 }
5116
5117 let original = Wrapper::<u8> {
5118 inner: vec![1, 2, 3],
5119 };
5120 let serialized = serialize(&original).unwrap();
5121 let deserialized: Wrapper<u8> = deserialize(&serialized).unwrap();
5122 assert_eq!(original, deserialized);
5123 }
5124
5125 #[test]
5126 fn test_generic_type_with_container_adapter_assoc() {
5127 trait HasAssoc {
5128 type Value: for<'de> SchemaRead<'de, DefaultConfig, Dst = Self::Value>
5129 + SchemaWrite<DefaultConfig, Src = Self::Value>
5130 + Clone
5131 + core::fmt::Debug
5132 + PartialEq;
5133 }
5134
5135 #[derive(Debug, PartialEq)]
5136 struct UsesU64;
5137 impl HasAssoc for UsesU64 {
5138 type Value = u64;
5139 }
5140
5141 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, Clone)]
5142 #[wincode(internal)]
5143 struct Wrapper<T: HasAssoc> {
5144 #[wincode(with = "containers::Vec<_, BincodeLen>")]
5145 inner: Vec<T::Value>,
5146 }
5147
5148 let original = Wrapper::<UsesU64> {
5149 inner: vec![42, 67],
5150 };
5151 let serialized = serialize(&original).unwrap();
5152 let deserialized: Wrapper<UsesU64> = deserialize(&serialized).unwrap();
5153 assert_eq!(original, deserialized);
5154 }
5155
5156 #[test]
5157 fn test_bool_write_is_zero_copy_and_roundtrips() {
5158 assert!(matches!(
5160 <bool as SchemaWrite<DefaultConfig>>::TYPE_META,
5161 TypeMeta::Static {
5162 size: 1,
5163 zero_copy: true
5164 }
5165 ));
5166
5167 let v: Vec<bool> = vec![true, false, true, true, false, false, true];
5169 let bytes = serialize(&v).unwrap();
5170 assert_eq!(bytes.len() - 8, v.len()); assert_eq!(deserialize::<Vec<bool>>(&bytes).unwrap(), v);
5172
5173 let a: [bool; 5] = [true, false, false, true, true];
5174 let bytes = serialize(&a).unwrap();
5175 assert_eq!(deserialize::<[bool; 5]>(&bytes).unwrap(), a);
5176 }
5177
5178 #[test]
5179 fn test_invalid_bool_byte_still_rejected_on_read() {
5180 assert!(matches!(
5183 <bool as SchemaRead<'_, DefaultConfig>>::TYPE_META,
5184 TypeMeta::Static {
5185 size: 1,
5186 zero_copy: false
5187 }
5188 ));
5189
5190 let mut bytes = serialize(&vec![true, false]).unwrap();
5192 *bytes.last_mut().unwrap() = 2; assert!(deserialize::<Vec<bool>>(&bytes).is_err());
5194 }
5195}