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