1use {
49 crate::{
50 config::{self, ConfigCore, DefaultConfig},
51 error::{ReadResult, WriteResult},
52 io::*,
53 len::SeqLen,
54 },
55 core::mem::MaybeUninit,
56};
57
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<'a, T, Len, C>(
426 value: impl ExactSizeIterator<Item = &'a T::Src>,
427) -> WriteResult<usize>
428where
429 C: ConfigCore,
430 Len: SeqLen<C>,
431 T: SchemaWrite<C> + 'a,
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(T::size_of)
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<'a, T, Len, C>(
458 mut writer: impl Writer,
459 src: impl ExactSizeIterator<Item = &'a T::Src>,
460) -> WriteResult<()>
461where
462 C: ConfigCore,
463 Len: SeqLen<C>,
464 T: SchemaWrite<C> + 'a,
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)?;
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)?;
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, ReadResult, SchemaRead, SchemaReadContext, SchemaWrite, Serialize,
556 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_enum_config_discriminant_override() {
2181 let config = Configuration::default().with_tag_encoding::<u8>();
2182
2183 #[derive(SchemaRead, SchemaWrite, Debug, PartialEq, Eq, proptest_derive::Arbitrary)]
2184 #[wincode(internal, tag_encoding = "u32")]
2185 enum Enum {
2186 A,
2187 B,
2188 }
2189
2190 assert_eq!(
2191 <Enum as SchemaRead<'_, _>>::type_meta(config),
2192 TypeMeta::Static {
2193 size: 4,
2194 zero_copy: false
2195 }
2196 );
2197
2198 assert_eq!(
2199 <Enum as SchemaWrite<_>>::type_meta(config),
2200 TypeMeta::Static {
2201 size: 4,
2202 zero_copy: false
2203 }
2204 );
2205
2206 proptest!(proptest_cfg(), |(e: Enum)| {
2207 let serialized = config::serialize(&e, config).unwrap();
2208 prop_assert_eq!(serialized.len(), 4);
2209 let discriminant = u32::from_le_bytes(serialized[0..4].try_into().unwrap());
2210 match e {
2211 Enum::A => prop_assert_eq!(discriminant, 0u32),
2212 Enum::B => prop_assert_eq!(discriminant, 1u32),
2213 }
2214 let deserialized: Enum = config::deserialize(&serialized, config).unwrap();
2215 prop_assert_eq!(deserialized, e);
2216 });
2217 }
2218
2219 #[test]
2220 fn test_enum_config_discriminant_u8_custom_tag() {
2221 let config = Configuration::default().with_tag_encoding::<u8>();
2222
2223 #[derive(SchemaRead, SchemaWrite, Debug, PartialEq, Eq, proptest_derive::Arbitrary)]
2224 #[wincode(internal)]
2225 enum Enum {
2226 #[wincode(tag = 2)]
2227 A,
2228 #[wincode(tag = 3)]
2229 B,
2230 #[wincode(tag = 5)]
2231 C,
2232 }
2233
2234 proptest!(proptest_cfg(), |(e: Enum)| {
2235 let serialized = config::serialize(&e, config).unwrap();
2236 prop_assert_eq!(serialized.len(), 1);
2237 match e {
2238 Enum::A => prop_assert_eq!(serialized[0], 2),
2239 Enum::B => prop_assert_eq!(serialized[0], 3),
2240 Enum::C => prop_assert_eq!(serialized[0], 5),
2241 }
2242 let deserialized: Enum = config::deserialize(&serialized, config).unwrap();
2243 prop_assert_eq!(deserialized, e);
2244 });
2245 }
2246
2247 #[test]
2248 fn test_phantom_data() {
2249 let val = PhantomData::<StructStatic>;
2250 let serialized = serialize(&val).unwrap();
2251 let bincode_serialized = bincode::serialize(&val).unwrap();
2252 assert_eq!(&serialized, &bincode_serialized);
2253 assert_eq!(
2254 <PhantomData<StructStatic> as SchemaWrite<DefaultConfig>>::size_of(&val).unwrap(),
2255 bincode::serialized_size(&val).unwrap() as usize
2256 );
2257 let deserialized: PhantomData<StructStatic> = deserialize(&serialized).unwrap();
2258 let bincode_deserialized: PhantomData<StructStatic> =
2259 bincode::deserialize(&bincode_serialized).unwrap();
2260 assert_eq!(deserialized, bincode_deserialized);
2261 }
2262
2263 #[test]
2264 fn test_unit() {
2265 let serialized = serialize(&()).unwrap();
2266 let bincode_serialized = bincode::serialize(&()).unwrap();
2267 assert_eq!(&serialized, &bincode_serialized);
2268 assert_eq!(
2269 <() as SchemaWrite<DefaultConfig>>::size_of(&()).unwrap(),
2270 bincode::serialized_size(&()).unwrap() as usize
2271 );
2272 assert!(deserialize::<()>(&serialized).is_ok());
2273 assert!(bincode::deserialize::<()>(&bincode_serialized).is_ok());
2274 }
2275
2276 #[test]
2277 fn test_duration_varint_type_meta_dynamic() {
2278 let config = Configuration::default().with_varint_encoding();
2279
2280 assert_eq!(
2281 <Duration as SchemaWrite<_>>::type_meta(config),
2282 TypeMeta::Dynamic
2283 );
2284 assert_eq!(
2285 <Duration as SchemaRead<'_, _>>::type_meta(config),
2286 TypeMeta::Dynamic
2287 );
2288
2289 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, Eq)]
2290 #[wincode(internal)]
2291 struct WithDuration {
2292 a: u8,
2293 d: Duration,
2294 b: u8,
2295 }
2296
2297 assert_eq!(
2298 <WithDuration as SchemaWrite<_>>::type_meta(config),
2299 TypeMeta::Dynamic
2300 );
2301 assert_eq!(
2302 <WithDuration as SchemaRead<'_, _>>::type_meta(config),
2303 TypeMeta::Dynamic
2304 );
2305
2306 let val = WithDuration {
2307 a: 1,
2308 d: Duration::new(0, 0),
2309 b: 2,
2310 };
2311
2312 assert_eq!(config::serialized_size(&val.d, config).unwrap(), 2);
2314
2315 let mut buf = [0xAAu8; 13];
2318 let written = {
2319 let buf_len = buf.len();
2320 let mut writer: &mut [u8] = &mut buf;
2321 config::serialize_into(&mut writer, &val, config).unwrap();
2322 buf_len - writer.len()
2323 };
2324 assert_eq!(written, 4);
2325 assert_eq!(&buf[..written], &[1, 0, 0, 2]);
2326 assert!(buf[written..].iter().all(|&b| b == 0xAA));
2327
2328 let roundtrip: WithDuration = config::deserialize(&buf[..written], config).unwrap();
2329 assert_eq!(roundtrip, val);
2330 }
2331
2332 #[test]
2333 fn test_system_time_varint_type_meta_dynamic() {
2334 let config = Configuration::default().with_varint_encoding();
2335
2336 assert_eq!(
2337 <SystemTime as SchemaWrite<_>>::type_meta(config),
2338 TypeMeta::Dynamic
2339 );
2340 assert_eq!(
2341 <SystemTime as SchemaRead<'_, _>>::type_meta(config),
2342 TypeMeta::Dynamic
2343 );
2344
2345 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, Eq)]
2346 #[wincode(internal)]
2347 struct WithSystemTime {
2348 a: u8,
2349 t: SystemTime,
2350 b: u8,
2351 }
2352
2353 assert_eq!(
2354 <WithSystemTime as SchemaWrite<_>>::type_meta(config),
2355 TypeMeta::Dynamic
2356 );
2357 assert_eq!(
2358 <WithSystemTime as SchemaRead<'_, _>>::type_meta(config),
2359 TypeMeta::Dynamic
2360 );
2361
2362 let val = WithSystemTime {
2363 a: 1,
2364 t: UNIX_EPOCH,
2365 b: 2,
2366 };
2367
2368 assert_eq!(config::serialized_size(&val.t, config).unwrap(), 2);
2370
2371 let mut buf = [0xAAu8; 13];
2372 let written = {
2373 let buf_len = buf.len();
2374 let mut writer: &mut [u8] = &mut buf;
2375 config::serialize_into(&mut writer, &val, config).unwrap();
2376 buf_len - writer.len()
2377 };
2378 assert_eq!(written, 4);
2379 assert_eq!(&buf[..written], &[1, 0, 0, 2]);
2380 assert!(buf[written..].iter().all(|&b| b == 0xAA));
2381
2382 let roundtrip: WithSystemTime = config::deserialize(&buf[..written], config).unwrap();
2383 assert_eq!(roundtrip, val);
2384 }
2385
2386 #[test]
2387 fn test_borrowed_bytes() {
2388 #[derive(
2389 SchemaWrite, SchemaRead, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize,
2390 )]
2391 #[wincode(internal)]
2392 struct BorrowedBytes<'a> {
2393 bytes: &'a [u8],
2394 }
2395
2396 proptest!(proptest_cfg(), |(bytes in proptest::collection::vec(any::<u8>(), 0..=100))| {
2397 let val = BorrowedBytes { bytes: &bytes };
2398 let bincode_serialized = bincode::serialize(&val).unwrap();
2399 let schema_serialized = serialize(&val).unwrap();
2400 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2401 let bincode_deserialized: BorrowedBytes = bincode::deserialize(&bincode_serialized).unwrap();
2402 let schema_deserialized: BorrowedBytes = deserialize(&schema_serialized).unwrap();
2403 prop_assert_eq!(&val, &bincode_deserialized);
2404 prop_assert_eq!(val, schema_deserialized);
2405 });
2406 }
2407
2408 #[test]
2409 fn test_boxed_slice_pod_drop() {
2410 #[derive(proptest_derive::Arbitrary, Debug, Clone, Copy)]
2411 #[allow(dead_code)]
2412 struct Signature([u8; 64]);
2413
2414 pod_wrapper! {
2415 unsafe struct PodSignature(Signature);
2416 }
2417
2418 type Target = containers::Box<[PodSignature], BincodeLen>;
2419 proptest!(proptest_cfg(), |(slice in proptest::collection::vec(any::<Signature>(), 1..=32).prop_map(|vec| vec.into_boxed_slice()))| {
2420 let serialized = Target::serialize(&slice).unwrap();
2421 let deserialized = Target::deserialize(&serialized[..serialized.len() - 32]);
2424 prop_assert!(deserialized.is_err());
2425 });
2426 }
2427
2428 #[test]
2429 fn test_zero_copy_padding_disqualification() {
2430 #[derive(SchemaWrite, SchemaRead)]
2431 #[wincode(internal)]
2432 #[repr(C, align(4))]
2433 struct Padded {
2434 a: u8,
2435 }
2436
2437 assert!(matches!(
2438 <Padded as SchemaWrite<DefaultConfig>>::TYPE_META,
2439 TypeMeta::Static {
2440 size: 1,
2442 zero_copy: false
2444 }
2445 ));
2446
2447 assert!(matches!(
2448 <Padded as SchemaRead<'_, DefaultConfig>>::TYPE_META,
2449 TypeMeta::Static {
2450 size: 1,
2452 zero_copy: false
2454 }
2455 ));
2456 }
2457
2458 proptest! {
2459 #![proptest_config(proptest_cfg())]
2460
2461 #[test]
2462 fn test_char(val in any::<char>()) {
2463 let bincode_serialized = bincode::serialize(&val).unwrap();
2464 let schema_serialized = serialize(&val).unwrap();
2465 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2466 prop_assert_eq!(<char as SchemaWrite<DefaultConfig>>::size_of(&val).unwrap(), bincode::serialized_size(&val).unwrap() as usize);
2467
2468 let bincode_deserialized: char = bincode::deserialize(&bincode_serialized).unwrap();
2469 let schema_deserialized: char = deserialize(&schema_serialized).unwrap();
2470 prop_assert_eq!(val, bincode_deserialized);
2471 prop_assert_eq!(val, schema_deserialized);
2472 }
2473
2474 #[test]
2475 fn test_vec_elem_static(vec in proptest::collection::vec(any::<StructStatic>(), 0..=100)) {
2476 let bincode_serialized = bincode::serialize(&vec).unwrap();
2477 let schema_serialized = serialize(&vec).unwrap();
2478 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2479
2480 let bincode_deserialized: Vec<StructStatic> = bincode::deserialize(&bincode_serialized).unwrap();
2481 let schema_deserialized: Vec<StructStatic> = deserialize(&schema_serialized).unwrap();
2482 prop_assert_eq!(&vec, &bincode_deserialized);
2483 prop_assert_eq!(vec, schema_deserialized);
2484 }
2485
2486 #[test]
2487 fn test_vec_elem_zero_copy(vec in proptest::collection::vec(any::<StructZeroCopy>(), 0..=100)) {
2488 let bincode_serialized = bincode::serialize(&vec).unwrap();
2489 let schema_serialized = serialize(&vec).unwrap();
2490 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2491
2492 let bincode_deserialized: Vec<StructZeroCopy> = bincode::deserialize(&bincode_serialized).unwrap();
2493 let schema_deserialized: Vec<StructZeroCopy> = deserialize(&schema_serialized).unwrap();
2494 prop_assert_eq!(&vec, &bincode_deserialized);
2495 prop_assert_eq!(vec, schema_deserialized);
2496 }
2497
2498 #[test]
2499 fn test_vec_elem_non_static(vec in proptest::collection::vec(any::<StructNonStatic>(), 0..=16)) {
2500 let bincode_serialized = bincode::serialize(&vec).unwrap();
2501 let schema_serialized = serialize(&vec).unwrap();
2502 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2503
2504 let bincode_deserialized: Vec<StructNonStatic> = bincode::deserialize(&bincode_serialized).unwrap();
2505 let schema_deserialized: Vec<StructNonStatic> = deserialize(&schema_serialized).unwrap();
2506 prop_assert_eq!(&vec, &bincode_deserialized);
2507 prop_assert_eq!(vec, schema_deserialized);
2508 }
2509
2510 #[test]
2511 fn test_vec_elem_bytes(vec in proptest::collection::vec(any::<u8>(), 0..=100)) {
2512 let bincode_serialized = bincode::serialize(&vec).unwrap();
2513 let schema_serialized = serialize(&vec).unwrap();
2514 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2515
2516 let bincode_deserialized: Vec<u8> = bincode::deserialize(&bincode_serialized).unwrap();
2517 let schema_deserialized: Vec<u8> = deserialize(&schema_serialized).unwrap();
2518 prop_assert_eq!(&vec, &bincode_deserialized);
2519 prop_assert_eq!(vec, schema_deserialized);
2520 }
2521
2522 #[test]
2523 fn test_serialize_slice(slice in proptest::collection::vec(any::<StructStatic>(), 0..=100)) {
2524 let bincode_serialized = bincode::serialize(slice.as_slice()).unwrap();
2525 let schema_serialized = serialize(slice.as_slice()).unwrap();
2526 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2527 }
2528
2529 #[test]
2530 fn test_vec_pod(vec in proptest::collection::vec(any::<[u8; 32]>(), 0..=100)) {
2531 let bincode_serialized = bincode::serialize(&vec).unwrap();
2532 let schema_serialized = serialize(&vec).unwrap();
2533 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2534
2535 let bincode_deserialized: Vec<[u8; 32]> = bincode::deserialize(&bincode_serialized).unwrap();
2536 let schema_deserialized: Vec<[u8; 32]> = deserialize(&schema_serialized).unwrap();
2537 prop_assert_eq!(&vec, &bincode_deserialized);
2538 prop_assert_eq!(vec, schema_deserialized);
2539 }
2540
2541 #[test]
2542 fn test_vec_deque_elem_static(vec in proptest::collection::vec_deque(any::<StructStatic>(), 0..=100)) {
2543 let bincode_serialized = bincode::serialize(&vec).unwrap();
2544 let schema_serialized = serialize(&vec).unwrap();
2545 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2546
2547 let bincode_deserialized: VecDeque<StructStatic> = bincode::deserialize(&bincode_serialized).unwrap();
2548 let schema_deserialized: VecDeque<StructStatic> = deserialize(&schema_serialized).unwrap();
2549 prop_assert_eq!(&vec, &bincode_deserialized);
2550 prop_assert_eq!(vec, schema_deserialized);
2551 }
2552
2553 #[test]
2554 fn test_vec_deque_elem_non_static(vec in proptest::collection::vec_deque(any::<StructNonStatic>(), 0..=16)) {
2555 let bincode_serialized = bincode::serialize(&vec).unwrap();
2556 let schema_serialized = serialize(&vec).unwrap();
2557 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2558
2559 let bincode_deserialized: VecDeque<StructNonStatic> = bincode::deserialize(&bincode_serialized).unwrap();
2560 let schema_deserialized: VecDeque<StructNonStatic> = deserialize(&schema_serialized).unwrap();
2561 prop_assert_eq!(&vec, &bincode_deserialized);
2562 prop_assert_eq!(vec, schema_deserialized);
2563 }
2564
2565 #[test]
2566 fn test_vec_deque_elem_bytes(vec in proptest::collection::vec_deque(any::<u8>(), 0..=100)) {
2567 let bincode_serialized = bincode::serialize(&vec).unwrap();
2568 let schema_serialized = serialize(&vec).unwrap();
2569 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2570
2571 let bincode_deserialized: VecDeque<u8> = bincode::deserialize(&bincode_serialized).unwrap();
2572 let schema_deserialized: VecDeque<u8> = deserialize(&schema_serialized).unwrap();
2573 prop_assert_eq!(&vec, &bincode_deserialized);
2574 prop_assert_eq!(vec, schema_deserialized);
2575 }
2576
2577 #[test]
2578 fn test_hash_map_zero_copy(map in proptest::collection::hash_map(any::<u8>(), any::<StructZeroCopy>(), 0..=100)) {
2579 let bincode_serialized = bincode::serialize(&map).unwrap();
2580 let schema_serialized = serialize(&map).unwrap();
2581 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2582
2583 let bincode_deserialized = bincode::deserialize(&bincode_serialized).unwrap();
2584 let schema_deserialized = deserialize(&schema_serialized).unwrap();
2585 prop_assert_eq!(&map, &bincode_deserialized);
2586 prop_assert_eq!(map, schema_deserialized);
2587 }
2588
2589 #[test]
2590 fn test_hash_map_static(map in proptest::collection::hash_map(any::<u64>(), any::<StructStatic>(), 0..=100)) {
2591 let bincode_serialized = bincode::serialize(&map).unwrap();
2592 let schema_serialized = serialize(&map).unwrap();
2593 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2594
2595 let bincode_deserialized = bincode::deserialize(&bincode_serialized).unwrap();
2596 let schema_deserialized = deserialize(&schema_serialized).unwrap();
2597 prop_assert_eq!(&map, &bincode_deserialized);
2598 prop_assert_eq!(map, schema_deserialized);
2599 }
2600
2601 #[test]
2602 fn test_hash_map_non_static(map in proptest::collection::hash_map(any::<u64>(), any::<StructNonStatic>(), 0..=16)) {
2603 let bincode_serialized = bincode::serialize(&map).unwrap();
2604 let schema_serialized = serialize(&map).unwrap();
2605 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2606
2607 let bincode_deserialized = bincode::deserialize(&bincode_serialized).unwrap();
2608 let schema_deserialized = deserialize(&schema_serialized).unwrap();
2609 prop_assert_eq!(&map, &bincode_deserialized);
2610 prop_assert_eq!(map, schema_deserialized);
2611 }
2612
2613 #[test]
2614 fn test_hash_set_zero_copy(set in proptest::collection::hash_set(any::<StructZeroCopy>(), 0..=100)) {
2615 let bincode_serialized = bincode::serialize(&set).unwrap();
2616 let schema_serialized = serialize(&set).unwrap();
2617 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2618
2619 let bincode_deserialized = bincode::deserialize(&bincode_serialized).unwrap();
2620 let schema_deserialized = deserialize(&schema_serialized).unwrap();
2621 prop_assert_eq!(&set, &bincode_deserialized);
2622 prop_assert_eq!(set, schema_deserialized);
2623 }
2624
2625 #[test]
2626 fn test_hash_set_static(set in proptest::collection::hash_set(any::<StructStatic>(), 0..=100)) {
2627 let bincode_serialized = bincode::serialize(&set).unwrap();
2628 let schema_serialized = serialize(&set).unwrap();
2629 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2630
2631 let bincode_deserialized = bincode::deserialize(&bincode_serialized).unwrap();
2632 let schema_deserialized = deserialize(&schema_serialized).unwrap();
2633 prop_assert_eq!(&set, &bincode_deserialized);
2634 prop_assert_eq!(set, schema_deserialized);
2635 }
2636
2637 #[test]
2638 fn test_hash_set_non_static(set in proptest::collection::hash_set(any::<StructNonStatic>(), 0..=16)) {
2639 let bincode_serialized = bincode::serialize(&set).unwrap();
2640 let schema_serialized = serialize(&set).unwrap();
2641 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2642
2643 let bincode_deserialized = bincode::deserialize(&bincode_serialized).unwrap();
2644 let schema_deserialized = deserialize(&schema_serialized).unwrap();
2645 prop_assert_eq!(&set, &bincode_deserialized);
2646 prop_assert_eq!(set, schema_deserialized);
2647 }
2648
2649 #[test]
2650 fn test_sequences_with_hasher(data in proptest::collection::hash_map(any::<String>(), any::<HashSet<u32>>(), 0..16)) {
2651 #[derive(Default)]
2652 struct SumHasher(u64);
2653
2654 impl BuildHasher for SumHasher {
2655 type Hasher = Self;
2656 fn build_hasher(&self) -> Self::Hasher {
2657 Self(0)
2658 }
2659 }
2660 impl Hasher for SumHasher {
2661 fn finish(&self) -> u64 {
2662 self.0
2663 }
2664
2665 fn write(&mut self, bytes: &[u8]) {
2666 self.0 += bytes.iter().map(|b| *b as u64).sum::<u64>();
2667 }
2668 }
2669
2670 type TestMap = HashMap<String, HashSet<u32, SumHasher>, SumHasher>;
2671 let test_data: TestMap = data.into_iter().map(|(k, v)| (k, HashSet::from_iter(v.into_iter()))).collect();
2672 let wincode_serialized = serialize(&test_data).unwrap();
2673 let bincode_serialized = bincode::serialize(&test_data).unwrap();
2674 prop_assert_eq!(&wincode_serialized, &bincode_serialized);
2675
2676 let wincode_deserialized: TestMap = deserialize(&wincode_serialized).unwrap();
2677 let bincode_deserialized: TestMap = bincode::deserialize(&bincode_serialized).unwrap();
2678 prop_assert_eq!(&test_data, &wincode_deserialized);
2679 prop_assert_eq!(wincode_deserialized, bincode_deserialized);
2680
2681 type RegularMap = HashMap<String, HashSet<u32>>;
2682 let regular_deserialized: RegularMap = deserialize(&wincode_serialized).unwrap();
2683 let regular_serialized = serialize(®ular_deserialized).unwrap();
2684 let test_deserialized: TestMap = deserialize(®ular_serialized).unwrap();
2685 prop_assert_eq!(test_data, test_deserialized);
2686 }
2687
2688
2689 #[test]
2690 fn test_btree_map_zero_copy(map in proptest::collection::btree_map(any::<u8>(), any::<StructZeroCopy>(), 0..=100)) {
2691 let bincode_serialized = bincode::serialize(&map).unwrap();
2692 let schema_serialized = serialize(&map).unwrap();
2693 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2694
2695 let bincode_deserialized = bincode::deserialize(&bincode_serialized).unwrap();
2696 let schema_deserialized = deserialize(&schema_serialized).unwrap();
2697 prop_assert_eq!(&map, &bincode_deserialized);
2698 prop_assert_eq!(map, schema_deserialized);
2699 }
2700
2701 #[test]
2702 fn test_btree_map_static(map in proptest::collection::btree_map(any::<u64>(), any::<StructStatic>(), 0..=100)) {
2703 let bincode_serialized = bincode::serialize(&map).unwrap();
2704 let schema_serialized = serialize(&map).unwrap();
2705 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2706
2707 let bincode_deserialized = bincode::deserialize(&bincode_serialized).unwrap();
2708 let schema_deserialized = deserialize(&schema_serialized).unwrap();
2709 prop_assert_eq!(&map, &bincode_deserialized);
2710 prop_assert_eq!(map, schema_deserialized);
2711 }
2712
2713 #[test]
2714 fn test_btree_map_non_static(map in proptest::collection::btree_map(any::<u64>(), any::<StructNonStatic>(), 0..=16)) {
2715 let bincode_serialized = bincode::serialize(&map).unwrap();
2716 let schema_serialized = serialize(&map).unwrap();
2717 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2718
2719 let bincode_deserialized = bincode::deserialize(&bincode_serialized).unwrap();
2720 let schema_deserialized = deserialize(&schema_serialized).unwrap();
2721 prop_assert_eq!(&map, &bincode_deserialized);
2722 prop_assert_eq!(map, schema_deserialized);
2723 }
2724
2725 #[test]
2726 fn test_btree_set_zero_copy(set in proptest::collection::btree_set(any::<StructZeroCopy>(), 0..=100)) {
2727 let bincode_serialized = bincode::serialize(&set).unwrap();
2728 let schema_serialized = serialize(&set).unwrap();
2729 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2730
2731 let bincode_deserialized = bincode::deserialize(&bincode_serialized).unwrap();
2732 let schema_deserialized = deserialize(&schema_serialized).unwrap();
2733 prop_assert_eq!(&set, &bincode_deserialized);
2734 prop_assert_eq!(set, schema_deserialized);
2735 }
2736
2737 #[test]
2738 fn test_btree_set_static(set in proptest::collection::btree_set(any::<StructStatic>(), 0..=100)) {
2739 let bincode_serialized = bincode::serialize(&set).unwrap();
2740 let schema_serialized = serialize(&set).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!(&set, &bincode_deserialized);
2746 prop_assert_eq!(set, schema_deserialized);
2747 }
2748
2749 #[test]
2750 fn test_btree_set_non_static(map in proptest::collection::btree_set(any::<StructNonStatic>(), 0..=16)) {
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_binary_heap_zero_copy(heap in proptest::collection::binary_heap(any::<StructZeroCopy>(), 0..=100)) {
2763 let bincode_serialized = bincode::serialize(&heap).unwrap();
2764 let schema_serialized = serialize(&heap).unwrap();
2765 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2766
2767 let bincode_deserialized: BinaryHeap<StructZeroCopy> = bincode::deserialize(&bincode_serialized).unwrap();
2768 let schema_deserialized: BinaryHeap<StructZeroCopy> = deserialize(&schema_serialized).unwrap();
2769 prop_assert_eq!(heap.as_slice(), bincode_deserialized.as_slice());
2770 prop_assert_eq!(heap.as_slice(), schema_deserialized.as_slice());
2771 }
2772
2773 #[test]
2774 fn test_binary_heap_static(heap in proptest::collection::binary_heap(any::<StructStatic>(), 0..=100)) {
2775 let bincode_serialized = bincode::serialize(&heap).unwrap();
2776 let schema_serialized = serialize(&heap).unwrap();
2777 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2778
2779 let bincode_deserialized: BinaryHeap<StructStatic> = bincode::deserialize(&bincode_serialized).unwrap();
2780 let schema_deserialized: BinaryHeap<StructStatic> = deserialize(&schema_serialized).unwrap();
2781 prop_assert_eq!(heap.as_slice(), bincode_deserialized.as_slice());
2782 prop_assert_eq!(heap.as_slice(), schema_deserialized.as_slice());
2783 }
2784
2785 #[test]
2786 fn test_binary_heap_non_static(heap in proptest::collection::binary_heap(any::<StructNonStatic>(), 0..=16)) {
2787 let bincode_serialized = bincode::serialize(&heap).unwrap();
2788 let schema_serialized = serialize(&heap).unwrap();
2789 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2790
2791 let bincode_deserialized: BinaryHeap<StructNonStatic> = bincode::deserialize(&bincode_serialized).unwrap();
2792 let schema_deserialized: BinaryHeap<StructNonStatic> = deserialize(&schema_serialized).unwrap();
2793 prop_assert_eq!(heap.as_slice(), bincode_deserialized.as_slice());
2794 prop_assert_eq!(heap.as_slice(), schema_deserialized.as_slice());
2795 }
2796
2797 #[test]
2798 fn test_linked_list_zero_copy(list in proptest::collection::linked_list(any::<StructZeroCopy>(), 0..=100)) {
2799 let bincode_serialized = bincode::serialize(&list).unwrap();
2800 let schema_serialized = serialize(&list).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!(&list, &bincode_deserialized);
2806 prop_assert_eq!(list, schema_deserialized);
2807 }
2808
2809 #[test]
2810 fn test_linked_list_static(list in proptest::collection::linked_list(any::<StructStatic>(), 0..=100)) {
2811 let bincode_serialized = bincode::serialize(&list).unwrap();
2812 let schema_serialized = serialize(&list).unwrap();
2813 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2814
2815 let bincode_deserialized = bincode::deserialize(&bincode_serialized).unwrap();
2816 let schema_deserialized = deserialize(&schema_serialized).unwrap();
2817 prop_assert_eq!(&list, &bincode_deserialized);
2818 prop_assert_eq!(list, schema_deserialized);
2819 }
2820
2821 #[test]
2822 fn test_linked_list_non_static(list in proptest::collection::linked_list(any::<StructNonStatic>(), 0..=16)) {
2823 let bincode_serialized = bincode::serialize(&list).unwrap();
2824 let schema_serialized = serialize(&list).unwrap();
2825 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2826
2827 let bincode_deserialized = bincode::deserialize(&bincode_serialized).unwrap();
2828 let schema_deserialized = deserialize(&schema_serialized).unwrap();
2829 prop_assert_eq!(&list, &bincode_deserialized);
2830 prop_assert_eq!(list, schema_deserialized);
2831 }
2832
2833 #[test]
2834 fn test_array_bytes(array in any::<[u8; 32]>()) {
2835 let bincode_serialized = bincode::serialize(&array).unwrap();
2836 let schema_serialized = serialize(&array).unwrap();
2837 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2838
2839 let bincode_deserialized: [u8; 32] = bincode::deserialize(&bincode_serialized).unwrap();
2840 let schema_deserialized: [u8; 32] = deserialize(&schema_serialized).unwrap();
2841 prop_assert_eq!(&array, &bincode_deserialized);
2842 prop_assert_eq!(array, schema_deserialized);
2843 }
2844
2845 #[test]
2846 fn test_array_static(array in any::<[u64; 32]>()) {
2847 let bincode_serialized = bincode::serialize(&array).unwrap();
2848 type Target = [u64; 32];
2849 let schema_serialized = Target::serialize(&array).unwrap();
2850 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2851 let bincode_deserialized: Target = bincode::deserialize(&bincode_serialized).unwrap();
2852 let schema_deserialized: Target = deserialize(&schema_serialized).unwrap();
2853 prop_assert_eq!(&array, &bincode_deserialized);
2854 prop_assert_eq!(array, schema_deserialized);
2855 }
2856
2857 #[test]
2858 fn test_array_non_static(array in any::<[StructNonStatic; 16]>()) {
2859 let bincode_serialized = bincode::serialize(&array).unwrap();
2860 type Target = [StructNonStatic; 16];
2861 let schema_serialized = Target::serialize(&array).unwrap();
2862 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2863 let bincode_deserialized: Target = bincode::deserialize(&bincode_serialized).unwrap();
2864 let schema_deserialized: Target = deserialize(&schema_serialized).unwrap();
2865 prop_assert_eq!(&array, &bincode_deserialized);
2866 prop_assert_eq!(array, schema_deserialized);
2867 }
2868
2869 #[test]
2870 fn test_option(option in proptest::option::of(any::<StructStatic>())) {
2871 let bincode_serialized = bincode::serialize(&option).unwrap();
2872 let schema_serialized = serialize(&option).unwrap();
2873
2874 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2875 let bincode_deserialized: Option<StructStatic> = bincode::deserialize(&bincode_serialized).unwrap();
2876 let schema_deserialized: Option<StructStatic> = deserialize(&schema_serialized).unwrap();
2877 prop_assert_eq!(&option, &bincode_deserialized);
2878 prop_assert_eq!(&option, &schema_deserialized);
2879 }
2880
2881 #[test]
2882 fn test_option_container(option in proptest::option::of(any::<[u8; 32]>())) {
2883 let bincode_serialized = bincode::serialize(&option).unwrap();
2884 type Target = Option<[u8; 32]>;
2885 let schema_serialized = Target::serialize(&option).unwrap();
2886 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2887 let bincode_deserialized: Option<[u8; 32]> = bincode::deserialize(&bincode_serialized).unwrap();
2888 let schema_deserialized: Option<[u8; 32]> = Target::deserialize(&schema_serialized).unwrap();
2889 prop_assert_eq!(&option, &bincode_deserialized);
2890 prop_assert_eq!(&option, &schema_deserialized);
2891 }
2892
2893 #[test]
2894 fn test_bool(val in any::<bool>()) {
2895 let bincode_serialized = bincode::serialize(&val).unwrap();
2896 let schema_serialized = serialize(&val).unwrap();
2897 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2898 let bincode_deserialized: bool = bincode::deserialize(&bincode_serialized).unwrap();
2899 let schema_deserialized: bool = deserialize(&schema_serialized).unwrap();
2900 prop_assert_eq!(val, bincode_deserialized);
2901 prop_assert_eq!(val, schema_deserialized);
2902 }
2903
2904 #[test]
2905 fn test_bool_invalid_bit_pattern(val in 2u8..=255) {
2906 let bincode_deserialized: Result<bool,_> = bincode::deserialize(&[val]);
2907 let schema_deserialized: Result<bool,_> = deserialize(&[val]);
2908 prop_assert!(bincode_deserialized.is_err());
2909 prop_assert!(schema_deserialized.is_err());
2910 }
2911
2912 #[test]
2913 fn test_box(s in any::<StructStatic>()) {
2914 let data = Box::new(s);
2915 let bincode_serialized = bincode::serialize(&data).unwrap();
2916 let schema_serialized = serialize(&data).unwrap();
2917 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2918
2919 let bincode_deserialized: Box<StructStatic> = bincode::deserialize(&bincode_serialized).unwrap();
2920 let schema_deserialized: Box<StructStatic> = deserialize(&schema_serialized).unwrap();
2921 prop_assert_eq!(&data, &bincode_deserialized);
2922 prop_assert_eq!(&data, &schema_deserialized);
2923 }
2924
2925 #[test]
2926 fn test_rc(s in any::<StructStatic>()) {
2927 let data = Rc::new(s);
2928 let bincode_serialized = bincode::serialize(&data).unwrap();
2929 let schema_serialized = serialize(&data).unwrap();
2930 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2931
2932 let bincode_deserialized: Rc<StructStatic> = bincode::deserialize(&bincode_serialized).unwrap();
2933 let schema_deserialized: Rc<StructStatic> = deserialize(&schema_serialized).unwrap();
2934 prop_assert_eq!(&data, &bincode_deserialized);
2935 prop_assert_eq!(&data, &schema_deserialized);
2936 }
2937
2938 #[test]
2939 fn test_arc(s in any::<StructStatic>()) {
2940 let data = Arc::new(s);
2941 let bincode_serialized = bincode::serialize(&data).unwrap();
2942 let schema_serialized = serialize(&data).unwrap();
2943 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2944
2945 let bincode_deserialized: Arc<StructStatic> = bincode::deserialize(&bincode_serialized).unwrap();
2946 let schema_deserialized: Arc<StructStatic> = deserialize(&schema_serialized).unwrap();
2947 prop_assert_eq!(&data, &bincode_deserialized);
2948 prop_assert_eq!(&data, &schema_deserialized);
2949 }
2950
2951 #[test]
2952 fn test_boxed_slice_zero_copy(vec in proptest::collection::vec(any::<StructZeroCopy>(), 0..=100)) {
2953 let data = vec.into_boxed_slice();
2954 let bincode_serialized = bincode::serialize(&data).unwrap();
2955 let schema_serialized = serialize(&data).unwrap();
2956 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2957
2958 let bincode_deserialized: Box<[StructZeroCopy]> = bincode::deserialize(&bincode_serialized).unwrap();
2959 let schema_deserialized: Box<[StructZeroCopy]> = deserialize(&schema_serialized).unwrap();
2960 prop_assert_eq!(&data, &bincode_deserialized);
2961 prop_assert_eq!(&data, &schema_deserialized);
2962 }
2963
2964 #[test]
2965 fn test_boxed_slice_static(vec in proptest::collection::vec(any::<StructStatic>(), 0..=100)) {
2966 let data = vec.into_boxed_slice();
2967 let bincode_serialized = bincode::serialize(&data).unwrap();
2968 let schema_serialized = serialize(&data).unwrap();
2969 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2970
2971 let bincode_deserialized: Box<[StructStatic]> = bincode::deserialize(&bincode_serialized).unwrap();
2972 let schema_deserialized: Box<[StructStatic]> = deserialize(&schema_serialized).unwrap();
2973 prop_assert_eq!(&data, &bincode_deserialized);
2974 prop_assert_eq!(&data, &schema_deserialized);
2975 }
2976
2977 #[test]
2978 fn test_boxed_slice_non_static(vec in proptest::collection::vec(any::<StructNonStatic>(), 0..=16)) {
2979 let data = vec.into_boxed_slice();
2980 let bincode_serialized = bincode::serialize(&data).unwrap();
2981 type Target = Box<[StructNonStatic]>;
2982 let schema_serialized = serialize(&data).unwrap();
2983 prop_assert_eq!(&bincode_serialized, &schema_serialized);
2984
2985 let bincode_deserialized: Target = bincode::deserialize(&bincode_serialized).unwrap();
2986 let schema_deserialized: Target = Target::deserialize(&schema_serialized).unwrap();
2987 prop_assert_eq!(&data, &bincode_deserialized);
2988 prop_assert_eq!(&data, &schema_deserialized);
2989 }
2990
2991 #[test]
2992 fn test_integers(
2993 val in (
2994 any::<u8>(),
2995 any::<i8>(),
2996 any::<u16>(),
2997 any::<i16>(),
2998 any::<u32>(),
2999 any::<i32>(),
3000 any::<usize>(),
3001 any::<isize>(),
3002 any::<u64>(),
3003 any::<i64>(),
3004 any::<u128>(),
3005 any::<i128>()
3006 )
3007 ) {
3008 type Target = (u8, i8, u16, i16, u32, i32, usize, isize, u64, i64, u128, i128);
3009 let bincode_serialized = bincode::serialize(&val).unwrap();
3010 let schema_serialized = serialize(&val).unwrap();
3011 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3012 let bincode_deserialized: Target = bincode::deserialize(&bincode_serialized).unwrap();
3013 let schema_deserialized: Target = deserialize(&schema_serialized).unwrap();
3014 prop_assert_eq!(val, bincode_deserialized);
3015 prop_assert_eq!(val, schema_deserialized);
3016 }
3017
3018 #[test]
3019 fn test_tuple_zero_copy(
3020 tuple in (
3021 any::<StructZeroCopy>(),
3022 any::<[u8; 32]>(),
3023 )
3024 ) {
3025 let bincode_serialized = bincode::serialize(&tuple).unwrap();
3026 let schema_serialized = serialize(&tuple).unwrap();
3027
3028 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3029 let bincode_deserialized = bincode::deserialize(&bincode_serialized).unwrap();
3030 let schema_deserialized = deserialize(&schema_serialized).unwrap();
3031 prop_assert_eq!(&tuple, &bincode_deserialized);
3032 prop_assert_eq!(&tuple, &schema_deserialized);
3033
3034 }
3035
3036 #[test]
3037 fn test_tuple_static(
3038 tuple in (
3039 any::<StructStatic>(),
3040 any::<[u8; 32]>(),
3041 )
3042 ) {
3043 let bincode_serialized = bincode::serialize(&tuple).unwrap();
3044 let schema_serialized = serialize(&tuple).unwrap();
3045
3046 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3047 let bincode_deserialized = bincode::deserialize(&bincode_serialized).unwrap();
3048 let schema_deserialized = deserialize(&schema_serialized).unwrap();
3049 prop_assert_eq!(&tuple, &bincode_deserialized);
3050 prop_assert_eq!(&tuple, &schema_deserialized);
3051
3052 }
3053
3054 #[test]
3055 fn test_tuple_non_static(
3056 tuple in (
3057 any::<StructNonStatic>(),
3058 any::<[u8; 32]>(),
3059 proptest::collection::vec(any::<StructStatic>(), 0..=100),
3060 )
3061 ) {
3062 let bincode_serialized = bincode::serialize(&tuple).unwrap();
3063 type BincodeTarget = (StructNonStatic, [u8; 32], Vec<StructStatic>);
3064 type Target = (StructNonStatic, [u8; 32], Vec<StructStatic>);
3065 let schema_serialized = Target::serialize(&tuple).unwrap();
3066
3067 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3068 let bincode_deserialized: BincodeTarget = bincode::deserialize(&bincode_serialized).unwrap();
3069 let schema_deserialized = Target::deserialize(&schema_serialized).unwrap();
3070 prop_assert_eq!(&tuple, &bincode_deserialized);
3071 prop_assert_eq!(&tuple, &schema_deserialized);
3072
3073 }
3074
3075 #[test]
3076 fn test_str(str in any::<String>()) {
3077 let bincode_serialized = bincode::serialize(&str).unwrap();
3078 let schema_serialized = serialize(&str).unwrap();
3079 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3080 let bincode_deserialized: &str = bincode::deserialize(&bincode_serialized).unwrap();
3081 let schema_deserialized: &str = deserialize(&schema_serialized).unwrap();
3082 prop_assert_eq!(&str, &bincode_deserialized);
3083 prop_assert_eq!(&str, &schema_deserialized);
3084
3085 let bincode_deserialized: String = bincode::deserialize(&bincode_serialized).unwrap();
3086 let schema_deserialized: String = deserialize(&schema_serialized).unwrap();
3087 prop_assert_eq!(&str, &bincode_deserialized);
3088 prop_assert_eq!(&str, &schema_deserialized);
3089 }
3090
3091 #[test]
3092 fn test_struct_zero_copy(val in any::<StructZeroCopy>()) {
3093 let bincode_serialized = bincode::serialize(&val).unwrap();
3094 let schema_serialized = serialize(&val).unwrap();
3095 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3096
3097 let bincode_deserialized = bincode::deserialize(&bincode_serialized).unwrap();
3098 let schema_deserialized = deserialize(&schema_serialized).unwrap();
3099 prop_assert_eq!(&val, &bincode_deserialized);
3100 prop_assert_eq!(&val, &schema_deserialized);
3101 }
3102
3103 #[test]
3104 fn test_struct_static(val in any::<StructStatic>()) {
3105 let bincode_serialized = bincode::serialize(&val).unwrap();
3106 let schema_serialized = serialize(&val).unwrap();
3107 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3108
3109 let bincode_deserialized = bincode::deserialize(&bincode_serialized).unwrap();
3110 let schema_deserialized = deserialize(&schema_serialized).unwrap();
3111 prop_assert_eq!(&val, &bincode_deserialized);
3112 prop_assert_eq!(&val, &schema_deserialized);
3113 }
3114
3115 #[test]
3116 fn test_struct_non_static(val in any::<StructNonStatic>()) {
3117 let bincode_serialized = bincode::serialize(&val).unwrap();
3118 let schema_serialized = serialize(&val).unwrap();
3119 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3120
3121 let bincode_deserialized = bincode::deserialize(&bincode_serialized).unwrap();
3122 let schema_deserialized = deserialize(&schema_serialized).unwrap();
3123 prop_assert_eq!(&val, &bincode_deserialized);
3124 prop_assert_eq!(&val, &schema_deserialized);
3125 }
3126
3127 #[test]
3128 fn test_floats(
3129 val in (
3130 any::<f32>(),
3131 any::<f64>(),
3132 )
3133 ) {
3134 let bincode_serialized = bincode::serialize(&val).unwrap();
3135 let schema_serialized = serialize(&val).unwrap();
3136 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3137
3138 let bincode_deserialized: (f32, f64) = bincode::deserialize(&bincode_serialized).unwrap();
3139 let schema_deserialized: (f32, f64) = deserialize(&schema_serialized).unwrap();
3140 prop_assert_eq!(val, bincode_deserialized);
3141 prop_assert_eq!(val, schema_deserialized);
3142 }
3143 }
3144
3145 #[test]
3146 fn test_struct_zero_copy_refs() {
3147 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, Eq, proptest_derive::Arbitrary)]
3149 #[wincode(internal)]
3150 #[repr(C)]
3151 struct Zc {
3152 a: u8,
3153 b: [u8; 64],
3154 c: i8,
3155 d: [i8; 64],
3156 }
3157
3158 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, Eq)]
3160 #[wincode(internal)]
3161 #[repr(C)]
3162 struct ZcRefs<'a> {
3163 a: &'a u8,
3164 b: &'a [u8; 64],
3165 c: &'a i8,
3166 d: &'a [i8; 64],
3167 }
3168
3169 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, Eq)]
3171 #[wincode(internal)]
3172 #[repr(transparent)]
3173 struct ZcWrapper<'a> {
3174 data: &'a Zc,
3175 }
3176
3177 impl<'a> From<&'a ZcRefs<'a>> for Zc {
3178 fn from(value: &'a ZcRefs<'a>) -> Self {
3179 Self {
3180 a: *value.a,
3181 b: *value.b,
3182 c: *value.c,
3183 d: *value.d,
3184 }
3185 }
3186 }
3187
3188 proptest!(proptest_cfg(), |(data in any::<Zc>())| {
3189 let serialized = serialize(&data).unwrap();
3190 let deserialized = Zc::deserialize(&serialized).unwrap();
3191 assert_eq!(data, deserialized);
3192
3193 let serialized_ref = serialize(&ZcRefs { a: &data.a, b: &data.b, c: &data.c, d: &data.d }).unwrap();
3194 assert_eq!(serialized_ref, serialized);
3195 let deserialized_ref = ZcRefs::deserialize(&serialized_ref).unwrap();
3196 assert_eq!(data, (&deserialized_ref).into());
3197
3198 let serialized_wrapper = serialize(&ZcWrapper { data: &data }).unwrap();
3199 assert_eq!(serialized_wrapper, serialized);
3200 let deserialized_wrapper = ZcWrapper::deserialize(&serialized_wrapper).unwrap();
3201 assert_eq!(data, *deserialized_wrapper.data);
3202 });
3203 }
3204
3205 #[test]
3206 fn test_zero_copy_ref_with_integer_types() {
3207 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, Eq)]
3208 #[wincode(internal)]
3209 struct ZcRef<'a> {
3210 x: &'a StructZeroCopy,
3211 }
3212
3213 proptest!(proptest_cfg(), |(data in any::<StructZeroCopy>())| {
3214 let serialized = serialize_aligned(&data).unwrap();
3215 let deserialized: ZcRef<'_> = deserialize(&serialized).unwrap();
3216 assert_eq!(data, *deserialized.x);
3217 });
3218 }
3219
3220 #[test]
3221 fn test_zero_copy_enum_with_integer_types() {
3222 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, Eq, proptest_derive::Arbitrary)]
3223 #[wincode(internal)]
3224 #[wincode(tag_encoding = "u128")]
3225 enum Enum {
3226 A,
3227 B(StructZeroCopy),
3228 }
3229
3230 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, Eq)]
3231 #[wincode(internal)]
3232 #[wincode(tag_encoding = "u128")]
3233 enum EnumRef<'a> {
3234 A,
3235 B(&'a StructZeroCopy),
3236 }
3237
3238 proptest!(proptest_cfg(), |(data in any::<Enum>())| {
3239 let serialized = serialize_aligned(&data).unwrap();
3240 let deserialized: EnumRef<'_> = deserialize(&serialized).unwrap();
3241 match data {
3242 Enum::A => prop_assert!(matches!(deserialized, EnumRef::A)),
3243 Enum::B(x) => prop_assert!(matches!(deserialized, EnumRef::B(y) if &x == y)),
3244 }
3245 });
3246 }
3247
3248 #[test]
3249 fn test_empty_struct() {
3250 #[derive(
3251 Debug,
3252 SchemaWrite,
3253 SchemaRead,
3254 Default,
3255 PartialEq,
3256 Eq,
3257 serde::Serialize,
3258 serde::Deserialize,
3259 )]
3260 #[wincode(internal)]
3261 struct EmptyStruct {}
3262
3263 let empty = EmptyStruct::default();
3264
3265 let bincode_serialized = bincode::serialize(&empty).unwrap();
3266 let schema_serialized = serialize(&empty).unwrap();
3267
3268 assert_eq!(bincode_serialized, schema_serialized);
3270 assert_eq!(bincode_serialized.len(), 0);
3271
3272 let bincode_deserialized: EmptyStruct = bincode::deserialize(&bincode_serialized).unwrap();
3273 let schema_deserialized: EmptyStruct = deserialize(&schema_serialized).unwrap();
3274
3275 assert_eq!(empty, bincode_deserialized);
3276 assert_eq!(empty, schema_deserialized);
3277 }
3278
3279 #[test]
3280 fn test_pod_zero_copy() {
3281 #[derive(Debug, PartialEq, Eq, proptest_derive::Arbitrary, Clone, Copy)]
3282 #[repr(transparent)]
3283 struct Address([u8; 64]);
3284
3285 pod_wrapper! {
3286 unsafe struct PodAddress(Address);
3287 }
3288
3289 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, Eq, proptest_derive::Arbitrary)]
3290 #[wincode(internal)]
3291 #[repr(C)]
3292 struct MyStruct {
3293 #[wincode(with = "PodAddress")]
3294 address: Address,
3295 }
3296
3297 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, Eq)]
3298 #[wincode(internal)]
3299 struct MyStructRef<'a> {
3300 inner: &'a MyStruct,
3301 }
3302
3303 proptest!(proptest_cfg(), |(data in any::<MyStruct>())| {
3304 let serialized = serialize(&data).unwrap();
3305 let deserialized = MyStruct::deserialize(&serialized).unwrap();
3306 assert_eq!(data, deserialized);
3307
3308 let serialized_ref = serialize(&MyStructRef { inner: &data }).unwrap();
3309 assert_eq!(serialized_ref, serialized);
3310 let deserialized_ref = MyStructRef::deserialize(&serialized_ref).unwrap();
3311 assert_eq!(data, *deserialized_ref.inner);
3312 });
3313 }
3314
3315 #[test]
3316 fn test_pod_zero_copy_explicit_ref() {
3317 #[derive(Debug, PartialEq, Eq, proptest_derive::Arbitrary, Clone, Copy)]
3318 #[repr(transparent)]
3319 struct Address([u8; 64]);
3320
3321 pod_wrapper! {
3322 unsafe struct PodAddress(Address);
3323 }
3324
3325 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, Eq)]
3326 #[wincode(internal)]
3327 struct MyStructRef<'a> {
3328 #[wincode(with = "&'a PodAddress")]
3329 address: &'a Address,
3330 }
3331
3332 #[derive(SchemaWrite, SchemaRead, Debug, PartialEq, Eq, proptest_derive::Arbitrary)]
3333 #[wincode(internal)]
3334 struct MyStruct {
3335 #[wincode(with = "PodAddress")]
3336 address: Address,
3337 }
3338
3339 proptest!(proptest_cfg(), |(data in any::<MyStruct>())| {
3340 let serialized = serialize(&data).unwrap();
3341 let deserialized = MyStruct::deserialize(&serialized).unwrap();
3342 assert_eq!(data, deserialized);
3343
3344 let serialized_ref = serialize(&MyStructRef { address: &data.address }).unwrap();
3345 assert_eq!(serialized_ref, serialized);
3346 let deserialized_ref = MyStructRef::deserialize(&serialized_ref).unwrap();
3347 assert_eq!(data.address, *deserialized_ref.address);
3348 });
3349 }
3350
3351 #[test]
3352 fn test_result_basic() {
3353 proptest!(proptest_cfg(), |(value: Result<u64, String>)| {
3354 let wincode_serialized = serialize(&value).unwrap();
3355 let bincode_serialized = bincode::serialize(&value).unwrap();
3356 prop_assert_eq!(&wincode_serialized, &bincode_serialized);
3357
3358 let wincode_deserialized: Result<u64, String> = deserialize(&wincode_serialized).unwrap();
3359 let bincode_deserialized: Result<u64, String> = bincode::deserialize(&bincode_serialized).unwrap();
3360 prop_assert_eq!(&value, &wincode_deserialized);
3361 prop_assert_eq!(wincode_deserialized, bincode_deserialized);
3362 });
3363 }
3364
3365 #[test]
3366 fn test_result_bincode_equivalence() {
3367 use serde::{Deserialize, Serialize};
3368
3369 #[derive(
3370 Serialize,
3371 Deserialize,
3372 Debug,
3373 PartialEq,
3374 Clone,
3375 proptest_derive::Arbitrary,
3376 SchemaWrite,
3377 SchemaRead,
3378 )]
3379 #[wincode(internal)]
3380 enum Error {
3381 NotFound,
3382 InvalidInput(String),
3383 Other(u32),
3384 }
3385
3386 proptest!(proptest_cfg(), |(value: Result<Vec<u8>, Error>)| {
3387 let wincode_serialized = serialize(&value).unwrap();
3388 let bincode_serialized = bincode::serialize(&value).unwrap();
3389 prop_assert_eq!(&wincode_serialized, &bincode_serialized);
3390
3391 let wincode_deserialized: Result<Vec<u8>, Error> = deserialize(&wincode_serialized).unwrap();
3392 let bincode_deserialized: Result<Vec<u8>, Error> = bincode::deserialize(&bincode_serialized).unwrap();
3393 prop_assert_eq!(&value, &wincode_deserialized);
3394 prop_assert_eq!(wincode_deserialized, bincode_deserialized);
3395 });
3396 }
3397
3398 #[test]
3399 fn test_result_nested() {
3400 proptest!(proptest_cfg(), |(value: Result<Result<u64, String>, u32>)| {
3401 let wincode_serialized = serialize(&value).unwrap();
3402 let bincode_serialized = bincode::serialize(&value).unwrap();
3403 prop_assert_eq!(&wincode_serialized, &bincode_serialized);
3404
3405 let wincode_deserialized: Result<Result<u64, String>, u32> = deserialize(&wincode_serialized).unwrap();
3406 let bincode_deserialized: Result<Result<u64, String>, u32> = bincode::deserialize(&bincode_serialized).unwrap();
3407 prop_assert_eq!(&value, &wincode_deserialized);
3408 prop_assert_eq!(wincode_deserialized, bincode_deserialized);
3409 });
3410 }
3411
3412 #[test]
3413 fn test_result_with_complex_types() {
3414 use std::collections::HashMap;
3415
3416 proptest!(proptest_cfg(), |(value: Result<HashMap<String, Vec<u32>>, bool>)| {
3417 let wincode_serialized = serialize(&value).unwrap();
3418 let bincode_serialized = bincode::serialize(&value).unwrap();
3419 prop_assert_eq!(&wincode_serialized, &bincode_serialized);
3420
3421 let wincode_deserialized: Result<HashMap<String, Vec<u32>>, bool> = deserialize(&wincode_serialized).unwrap();
3422 let bincode_deserialized: Result<HashMap<String, Vec<u32>>, bool> = bincode::deserialize(&bincode_serialized).unwrap();
3423 prop_assert_eq!(&value, &wincode_deserialized);
3424 prop_assert_eq!(wincode_deserialized, bincode_deserialized);
3425 });
3426 }
3427
3428 #[test]
3429 fn test_result_type_meta_static() {
3430 assert!(matches!(
3432 <Result<u64, u64> as SchemaRead<DefaultConfig>>::TYPE_META,
3433 TypeMeta::Static {
3434 size: 12,
3435 zero_copy: false
3436 }
3437 ));
3438
3439 proptest!(proptest_cfg(), |(value: Result<u64, u64>)| {
3440 let wincode_serialized = serialize(&value).unwrap();
3441 let bincode_serialized = bincode::serialize(&value).unwrap();
3442 prop_assert_eq!(&wincode_serialized, &bincode_serialized);
3443
3444 let wincode_deserialized: Result<u64, u64> = deserialize(&wincode_serialized).unwrap();
3445 let bincode_deserialized: Result<u64, u64> = bincode::deserialize(&bincode_serialized).unwrap();
3446 prop_assert_eq!(&value, &wincode_deserialized);
3447 prop_assert_eq!(wincode_deserialized, bincode_deserialized);
3448 });
3449 }
3450
3451 #[test]
3452 fn test_result_type_meta_dynamic() {
3453 assert!(matches!(
3455 <Result<u64, String> as SchemaRead<DefaultConfig>>::TYPE_META,
3456 TypeMeta::Dynamic
3457 ));
3458
3459 proptest!(proptest_cfg(), |(value: Result<u64, String>)| {
3460 let wincode_serialized = serialize(&value).unwrap();
3461 let bincode_serialized = bincode::serialize(&value).unwrap();
3462 prop_assert_eq!(&wincode_serialized, &bincode_serialized);
3463
3464 let wincode_deserialized: Result<u64, String> = deserialize(&wincode_serialized).unwrap();
3465 let bincode_deserialized: Result<u64, String> = bincode::deserialize(&bincode_serialized).unwrap();
3466 prop_assert_eq!(&value, &wincode_deserialized);
3467 prop_assert_eq!(wincode_deserialized, bincode_deserialized);
3468 });
3469 }
3470
3471 #[test]
3472 fn test_result_type_meta_different_sizes() {
3473 assert!(matches!(
3475 <Result<u64, u32> as SchemaRead<DefaultConfig>>::TYPE_META,
3476 TypeMeta::Dynamic
3477 ));
3478
3479 proptest!(proptest_cfg(), |(value: Result<u64, u32>)| {
3480 let wincode_serialized = serialize(&value).unwrap();
3481 let bincode_serialized = bincode::serialize(&value).unwrap();
3482 prop_assert_eq!(&wincode_serialized, &bincode_serialized);
3483
3484 let wincode_deserialized: Result<u64, u32> = deserialize(&wincode_serialized).unwrap();
3485 let bincode_deserialized: Result<u64, u32> = bincode::deserialize(&bincode_serialized).unwrap();
3486 prop_assert_eq!(&value, &wincode_deserialized);
3487 prop_assert_eq!(wincode_deserialized, bincode_deserialized);
3488 });
3489 }
3490
3491 struct BufAligned {
3497 buf: *mut u8,
3498 layout: Layout,
3499 }
3500
3501 impl Deref for BufAligned {
3502 type Target = [u8];
3503
3504 fn deref(&self) -> &Self::Target {
3505 unsafe { core::slice::from_raw_parts(self.buf as *const u8, self.layout.size()) }
3506 }
3507 }
3508
3509 impl DerefMut for BufAligned {
3510 fn deref_mut(&mut self) -> &mut Self::Target {
3511 unsafe { core::slice::from_raw_parts_mut(self.buf, self.layout.size()) }
3512 }
3513 }
3514
3515 impl Drop for BufAligned {
3516 fn drop(&mut self) {
3517 use alloc::alloc::dealloc;
3518 unsafe { dealloc(self.buf, self.layout) }
3519 }
3520 }
3521
3522 fn serialize_aligned<T>(src: &T) -> WriteResult<BufAligned>
3524 where
3525 T: SchemaWrite<DefaultConfig, Src = T>,
3526 {
3527 use alloc::alloc::alloc;
3528 let size = T::size_of(src)?;
3529 let layout = Layout::from_size_align(size, align_of::<T>()).unwrap();
3530 let mem = unsafe { alloc(layout) };
3531 if mem.is_null() {
3532 return Err(crate::WriteError::Custom("could not allocate"));
3533 }
3534 let mut buf = BufAligned { buf: mem, layout };
3535 crate::serialize_into(buf.deref_mut(), src)?;
3536 Ok(buf)
3537 }
3538
3539 #[test]
3540 fn test_zero_copy_mut_roundrip() {
3541 proptest!(proptest_cfg(), |(data: StructZeroCopy, data_rand: StructZeroCopy)| {
3542 let mut serialized = serialize_aligned(&data).unwrap();
3543 let deserialized: StructZeroCopy = deserialize(&serialized).unwrap();
3544 prop_assert_eq!(deserialized, data);
3545
3546
3547 {
3549 let ref_mut = StructZeroCopy::from_bytes_mut(&mut serialized).unwrap();
3550 *ref_mut = data_rand;
3551 }
3552 let deserialized: StructZeroCopy = deserialize(&serialized).unwrap();
3555 prop_assert_eq!(deserialized, data_rand);
3556 });
3557 }
3558
3559 #[test]
3560 fn test_deserialize_mut_roundrip() {
3561 proptest!(proptest_cfg(), |(data: StructZeroCopy, data_rand: StructZeroCopy)| {
3562 let mut serialized = serialize_aligned(&data).unwrap();
3563 let deserialized: StructZeroCopy = deserialize(&serialized).unwrap();
3564 prop_assert_eq!(deserialized, data);
3565
3566
3567 {
3569 let ref_mut: &mut StructZeroCopy = deserialize_mut(&mut serialized).unwrap();
3570 *ref_mut = data_rand;
3571 }
3572 let deserialized: StructZeroCopy = deserialize(&serialized).unwrap();
3575 prop_assert_eq!(deserialized, data_rand);
3576 });
3577 }
3578
3579 #[test]
3580 fn test_zero_copy_deserialize_ref() {
3581 proptest!(proptest_cfg(), |(data: StructZeroCopy)| {
3582 let serialized = serialize_aligned(&data).unwrap();
3583 let deserialized: StructZeroCopy = deserialize(&serialized).unwrap();
3584 prop_assert_eq!(deserialized, data);
3585
3586 let ref_data = StructZeroCopy::from_bytes(&serialized).unwrap();
3587 prop_assert_eq!(ref_data, &data);
3588 });
3589 }
3590
3591 #[test]
3592 fn test_custom_preallocation_size_limit() {
3593 let c = Configuration::default().with_preallocation_size_limit::<64>();
3594 proptest!(proptest_cfg(), |(value in proptest::collection::vec(any::<u8>(), 0..=128))| {
3595 let wincode_serialized = crate::serialize(&value).unwrap();
3596 let wincode_deserialized: Result<Vec<u8>, _> = config::deserialize(&wincode_serialized, c);
3597 if value.len() <= 64 {
3598 prop_assert_eq!(value, wincode_deserialized.unwrap());
3599 } else {
3600 prop_assert!(wincode_deserialized.is_err());
3601 }
3602 });
3603 }
3604
3605 #[test]
3606 fn test_custom_length_encoding() {
3607 let c = Configuration::default().with_length_encoding::<FixIntLen<u32>>();
3608
3609 proptest!(proptest_cfg(), |(value: Vec<u8>)| {
3610 let wincode_serialized = config::serialize(&value, c).unwrap();
3611 let wincode_deserialized: Vec<u8> = config::deserialize(&wincode_serialized, c).unwrap();
3612 let len = value.len();
3613 prop_assert_eq!(len, u32::from_le_bytes(wincode_serialized[0..4].try_into().unwrap()) as usize);
3614 prop_assert_eq!(value, wincode_deserialized);
3615 });
3616 }
3617
3618 #[test]
3619 fn test_duration() {
3620 use core::time::Duration;
3621
3622 proptest!(proptest_cfg(), |(val: Duration)| {
3623 let bincode_serialized = bincode::serialize(&val).unwrap();
3624 let schema_serialized = serialize(&val).unwrap();
3625 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3626
3627 let bincode_deserialized: Duration = bincode::deserialize(&bincode_serialized).unwrap();
3628 let schema_deserialized: Duration = deserialize(&schema_serialized).unwrap();
3629 prop_assert_eq!(val, bincode_deserialized);
3630 prop_assert_eq!(val, schema_deserialized);
3631 });
3632 }
3633
3634 #[test]
3635 fn test_ipv4_addr() {
3636 proptest!(proptest_cfg(), |(addr: Ipv4Addr)| {
3637 let bincode_serialized = bincode::serialize(&addr).unwrap();
3638 let schema_serialized = serialize(&addr).unwrap();
3639 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3640
3641 let bincode_deserialized: Ipv4Addr = bincode::deserialize(&bincode_serialized).unwrap();
3642 let schema_deserialized: Ipv4Addr = deserialize(&schema_serialized).unwrap();
3643 prop_assert_eq!(addr, bincode_deserialized);
3644 prop_assert_eq!(addr, schema_deserialized);
3645 });
3646 }
3647
3648 #[test]
3649 fn test_ipv6_addr() {
3650 proptest!(proptest_cfg(), |(addr: Ipv6Addr)| {
3651 let bincode_serialized = bincode::serialize(&addr).unwrap();
3652 let schema_serialized = serialize(&addr).unwrap();
3653 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3654
3655 let bincode_deserialized: Ipv6Addr = bincode::deserialize(&bincode_serialized).unwrap();
3656 let schema_deserialized: Ipv6Addr = deserialize(&schema_serialized).unwrap();
3657 prop_assert_eq!(addr, bincode_deserialized);
3658 prop_assert_eq!(addr, schema_deserialized);
3659 });
3660 }
3661
3662 #[test]
3663 fn test_ip_addr() {
3664 proptest!(proptest_cfg(), |(addr: IpAddr)| {
3665 let bincode_serialized = bincode::serialize(&addr).unwrap();
3666 let schema_serialized = serialize(&addr).unwrap();
3667 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3668
3669 let bincode_deserialized: IpAddr = bincode::deserialize(&bincode_serialized).unwrap();
3670 let schema_deserialized: IpAddr = deserialize(&schema_serialized).unwrap();
3671 prop_assert_eq!(addr, bincode_deserialized);
3672 prop_assert_eq!(addr, schema_deserialized);
3673 });
3674 }
3675
3676 #[test]
3677 fn test_socket_addr_v4() {
3678 proptest!(proptest_cfg(), |(addr: SocketAddrV4)| {
3679 let bincode_serialized = bincode::serialize(&addr).unwrap();
3680 let schema_serialized = serialize(&addr).unwrap();
3681 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3682
3683 let bincode_deserialized: SocketAddrV4 = bincode::deserialize(&bincode_serialized).unwrap();
3684 let schema_deserialized: SocketAddrV4 = deserialize(&schema_serialized).unwrap();
3685 prop_assert_eq!(addr, bincode_deserialized);
3686 prop_assert_eq!(addr, schema_deserialized);
3687 });
3688 }
3689
3690 #[test]
3691 fn test_socket_addr_v6() {
3692 proptest!(proptest_cfg(), |(addr: SocketAddrV6)| {
3695 let bincode_serialized = bincode::serialize(&addr).unwrap();
3696 let schema_serialized = serialize(&addr).unwrap();
3697 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3698
3699 let bincode_deserialized: SocketAddrV6 = bincode::deserialize(&bincode_serialized).unwrap();
3700 let schema_deserialized: SocketAddrV6 = deserialize(&schema_serialized).unwrap();
3701 prop_assert_eq!(bincode_deserialized, schema_deserialized);
3702 });
3703 }
3704
3705 #[test]
3706 fn test_socket_addr() {
3707 proptest!(proptest_cfg(), |(addr: SocketAddr)| {
3710 let bincode_serialized = bincode::serialize(&addr).unwrap();
3711 let schema_serialized = serialize(&addr).unwrap();
3712 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3713
3714 let bincode_deserialized: SocketAddr = bincode::deserialize(&bincode_serialized).unwrap();
3715 let schema_deserialized: SocketAddr = deserialize(&schema_serialized).unwrap();
3716 prop_assert_eq!(bincode_deserialized, schema_deserialized);
3717 });
3718 }
3719
3720 #[test]
3721 #[cfg(feature = "std")]
3722 fn test_system_time() {
3723 use std::time::{Duration, SystemTime, UNIX_EPOCH};
3724
3725 const MAX_SECS: u64 = i64::MAX as u64 - 1;
3726
3727 proptest!(proptest_cfg(), |(secs in 0u64..=MAX_SECS, nanos in 0u32..1_000_000_000u32)| {
3728 let time = UNIX_EPOCH + Duration::new(secs, nanos);
3729 let bincode_serialized = bincode::serialize(&time).unwrap();
3730 let schema_serialized = serialize(&time).unwrap();
3731 prop_assert_eq!(&bincode_serialized, &schema_serialized);
3732
3733 let bincode_deserialized: SystemTime = bincode::deserialize(&bincode_serialized).unwrap();
3734 let schema_deserialized: SystemTime = deserialize(&schema_serialized).unwrap();
3735 prop_assert_eq!(time, bincode_deserialized);
3736 prop_assert_eq!(time, schema_deserialized);
3737 });
3738 }
3739
3740 #[test]
3741 #[cfg(feature = "std")]
3742 fn test_system_time_before_epoch_errors() {
3743 use std::time::{Duration, UNIX_EPOCH};
3744
3745 let before_epoch = UNIX_EPOCH.checked_sub(Duration::from_secs(1)).unwrap();
3746 assert!(serialize(&before_epoch).is_err());
3747 }
3748
3749 #[test]
3750 fn test_deserialize_exact_accepts_exact_input() {
3751 let bytes = serialize(&123u64).unwrap();
3752 let value: u64 = deserialize_exact(&bytes).unwrap();
3753 assert_eq!(value, 123);
3754 }
3755
3756 #[test]
3757 fn test_deserialize_exact_rejects_trailing_bytes() {
3758 let mut bytes = serialize(&123u64).unwrap();
3759 bytes.push(0xAA);
3760 let err = deserialize_exact::<u64>(&bytes).unwrap_err();
3761 assert!(matches!(err, error::ReadError::TrailingBytes));
3762 }
3763
3764 #[test]
3765 fn test_config_deserialize_exact_rejects_trailing_bytes() {
3766 let config = Configuration::default();
3767 let mut bytes = config::serialize(&123u64, config).unwrap();
3768 bytes.push(0xAA);
3769 let err = config::deserialize_exact::<u64, _>(&bytes, config).unwrap_err();
3770 assert!(matches!(err, error::ReadError::TrailingBytes));
3771 }
3772
3773 #[test]
3774 #[cfg(feature = "std")]
3775 fn test_system_time_overflow_errors() {
3776 use {crate::serialize_into, std::time::SystemTime};
3777
3778 let mut bytes = Vec::with_capacity(size_of::<u64>() + size_of::<u32>());
3779 serialize_into(&mut bytes, &u64::MAX).unwrap();
3780 serialize_into(&mut bytes, &0u32).unwrap();
3781
3782 let result: ReadResult<SystemTime> = deserialize(&bytes);
3783 assert!(result.is_err());
3784 }
3785
3786 #[test]
3787 fn test_nonzero_types() {
3788 proptest!(proptest_cfg(), |(
3789 nz_u8: NonZeroU8,
3790 nz_u16: NonZeroU16,
3791 nz_u32: NonZeroU32,
3792 nz_u64: NonZeroU64,
3793 nz_u128: NonZeroU128,
3794 nz_usize: NonZeroUsize,
3795 nz_i8: NonZeroI8,
3796 nz_i16: NonZeroI16,
3797 nz_i32: NonZeroI32,
3798 nz_i64: NonZeroI64,
3799 nz_i128: NonZeroI128,
3800 nz_isize: NonZeroIsize,
3801 )| {
3802 let ser = serialize(&nz_u8).unwrap();
3804 let de: NonZeroU8 = deserialize(&ser).unwrap();
3805 prop_assert_eq!(nz_u8, de);
3806
3807 let ser = serialize(&nz_u16).unwrap();
3808 let de: NonZeroU16 = deserialize(&ser).unwrap();
3809 prop_assert_eq!(nz_u16, de);
3810
3811 let ser = serialize(&nz_u32).unwrap();
3812 let de: NonZeroU32 = deserialize(&ser).unwrap();
3813 prop_assert_eq!(nz_u32, de);
3814
3815 let ser = serialize(&nz_u64).unwrap();
3816 let de: NonZeroU64 = deserialize(&ser).unwrap();
3817 prop_assert_eq!(nz_u64, de);
3818
3819 let ser = serialize(&nz_u128).unwrap();
3820 let de: NonZeroU128 = deserialize(&ser).unwrap();
3821 prop_assert_eq!(nz_u128, de);
3822
3823 let ser = serialize(&nz_usize).unwrap();
3824 let de: NonZeroUsize = deserialize(&ser).unwrap();
3825 prop_assert_eq!(nz_usize, de);
3826
3827 let ser = serialize(&nz_i8).unwrap();
3829 let de: NonZeroI8 = deserialize(&ser).unwrap();
3830 prop_assert_eq!(nz_i8, de);
3831
3832 let ser = serialize(&nz_i16).unwrap();
3833 let de: NonZeroI16 = deserialize(&ser).unwrap();
3834 prop_assert_eq!(nz_i16, de);
3835
3836 let ser = serialize(&nz_i32).unwrap();
3837 let de: NonZeroI32 = deserialize(&ser).unwrap();
3838 prop_assert_eq!(nz_i32, de);
3839
3840 let ser = serialize(&nz_i64).unwrap();
3841 let de: NonZeroI64 = deserialize(&ser).unwrap();
3842 prop_assert_eq!(nz_i64, de);
3843
3844 let ser = serialize(&nz_i128).unwrap();
3845 let de: NonZeroI128 = deserialize(&ser).unwrap();
3846 prop_assert_eq!(nz_i128, de);
3847
3848 let ser = serialize(&nz_isize).unwrap();
3849 let de: NonZeroIsize = deserialize(&ser).unwrap();
3850 prop_assert_eq!(nz_isize, de);
3851 });
3852 }
3853
3854 #[test]
3855 fn test_nonzero_invalid_zero_value() {
3856 let zero_bytes = serialize(&0u32).unwrap();
3858 let result: ReadResult<NonZeroU32> = deserialize(&zero_bytes);
3859 assert!(
3860 result.is_err(),
3861 "Deserializing zero should fail for NonZeroU32"
3862 );
3863
3864 let zero_bytes = serialize(&0u64).unwrap();
3865 let result: ReadResult<NonZeroU64> = deserialize(&zero_bytes);
3866 assert!(
3867 result.is_err(),
3868 "Deserializing zero should fail for NonZeroU64"
3869 );
3870 }
3871
3872 #[test]
3873 fn test_bound_included_u64() {
3874 proptest!(proptest_cfg(), |(value in any::<u64>())| {
3875 let bound = Bound::Included(value);
3876 let serialized = serialize(&bound).unwrap();
3877 let deserialized: Bound<u64> = deserialize(&serialized).unwrap();
3878 prop_assert_eq!(&bound, &deserialized);
3879 });
3880 }
3881
3882 #[test]
3883 fn test_bound_excluded_u64() {
3884 proptest!(proptest_cfg(), |(value in any::<u64>())| {
3885 let bound = Bound::Excluded(value);
3886 let serialized = serialize(&bound).unwrap();
3887 let deserialized: Bound<u64> = deserialize(&serialized).unwrap();
3888 prop_assert_eq!(&bound, &deserialized);
3889 });
3890 }
3891
3892 #[test]
3893 fn test_bound_included_string() {
3894 proptest!(proptest_cfg(), |(value in any::<String>())| {
3895 let bound = Bound::Included(value);
3896 let serialized = serialize(&bound).unwrap();
3897 let deserialized: Bound<String> = deserialize(&serialized).unwrap();
3898 prop_assert_eq!(&bound, &deserialized);
3899 });
3900 }
3901
3902 #[test]
3903 fn test_bound_excluded_string() {
3904 proptest!(proptest_cfg(), |(value in any::<String>())| {
3905 let bound = Bound::Excluded(value);
3906 let serialized = serialize(&bound).unwrap();
3907 let deserialized: Bound<String> = deserialize(&serialized).unwrap();
3908 prop_assert_eq!(&bound, &deserialized);
3909 });
3910 }
3911
3912 #[test]
3913 fn test_bound_included_bincode_equivalence() {
3914 proptest!(proptest_cfg(), |(value in any::<u64>())| {
3915 let bound = Bound::Included(value);
3916 let wincode_serialized = serialize(&bound).unwrap();
3917 let bincode_serialized = bincode::serialize(&bound).unwrap();
3918 prop_assert_eq!(&wincode_serialized, &bincode_serialized);
3919
3920 let wincode_deserialized: Bound<u64> = deserialize(&wincode_serialized).unwrap();
3921 let bincode_deserialized: Bound<u64> = bincode::deserialize(&bincode_serialized).unwrap();
3922 prop_assert_eq!(&bound, &wincode_deserialized);
3923 prop_assert_eq!(&wincode_deserialized, &bincode_deserialized);
3924 });
3925 }
3926
3927 #[test]
3928 fn test_bound_excluded_bincode_equivalence() {
3929 proptest!(proptest_cfg(), |(value in any::<u64>())| {
3930 let bound = Bound::Excluded(value);
3931 let wincode_serialized = serialize(&bound).unwrap();
3932 let bincode_serialized = bincode::serialize(&bound).unwrap();
3933 prop_assert_eq!(&wincode_serialized, &bincode_serialized);
3934
3935 let wincode_deserialized: Bound<u64> = deserialize(&wincode_serialized).unwrap();
3936 let bincode_deserialized: Bound<u64> = bincode::deserialize(&bincode_serialized).unwrap();
3937 prop_assert_eq!(&bound, &wincode_deserialized);
3938 prop_assert_eq!(&wincode_deserialized, &bincode_deserialized);
3939 });
3940 }
3941
3942 #[test]
3943 fn test_range_u64() {
3944 proptest!(proptest_cfg(), |(start in any::<u64>(), end in any::<u64>())| {
3945 let range = Range { start, end };
3946 let serialized = serialize(&range).unwrap();
3947 let deserialized: Range<u64> = deserialize(&serialized).unwrap();
3948 prop_assert_eq!(range.start, deserialized.start);
3949 prop_assert_eq!(range.end, deserialized.end);
3950 });
3951 }
3952
3953 #[test]
3954 fn test_range_string() {
3955 proptest!(proptest_cfg(), |(start in any::<String>(), end in any::<String>())| {
3956 let range = Range { start, end };
3957 let serialized = serialize(&range).unwrap();
3958 let deserialized: Range<String> = deserialize(&serialized).unwrap();
3959 prop_assert_eq!(&range.start, &deserialized.start);
3960 prop_assert_eq!(&range.end, &deserialized.end);
3961 });
3962 }
3963
3964 #[test]
3965 fn test_range_bincode_equivalence() {
3966 proptest!(proptest_cfg(), |(start in any::<u64>(), end in any::<u64>())| {
3967 let range = Range { start, end };
3968 let wincode_serialized = serialize(&range).unwrap();
3969 let bincode_serialized = bincode::serialize(&range).unwrap();
3970 prop_assert_eq!(&wincode_serialized, &bincode_serialized);
3971
3972 let wincode_deserialized: Range<u64> = deserialize(&wincode_serialized).unwrap(); let bincode_deserialized: Range<u64> = bincode::deserialize(&bincode_serialized).unwrap();
3974 prop_assert_eq!(range.start, wincode_deserialized.start);
3975 prop_assert_eq!(range.end, wincode_deserialized.end);
3976 prop_assert_eq!(wincode_deserialized.start, bincode_deserialized.start);
3977 prop_assert_eq!(wincode_deserialized.end, bincode_deserialized.end);
3978 });
3979 }
3980
3981 #[test]
3982 fn test_range_inclusive_u64() {
3983 proptest!(proptest_cfg(), |(start in any::<u64>(), end in any::<u64>())| {
3984 let range = RangeInclusive::new(start, end);
3985 let serialized = serialize(&range).unwrap();
3986 let deserialized: RangeInclusive<u64> = deserialize(&serialized).unwrap();
3987 prop_assert_eq!(range.start(), deserialized.start());
3988 prop_assert_eq!(range.end(), deserialized.end());
3989 });
3990 }
3991
3992 #[test]
3993 fn test_range_inclusive_string() {
3994 proptest!(proptest_cfg(), |(start in any::<String>(), end in any::<String>())| {
3995 let range = RangeInclusive::new(start, end );
3996 let serialized = serialize(&range).unwrap();
3997 let deserialized: RangeInclusive<String> = deserialize(&serialized).unwrap();
3998 prop_assert_eq!(&range.start(), &deserialized.start());
3999 prop_assert_eq!(&range.end(), &deserialized.end());
4000 });
4001 }
4002
4003 #[test]
4004 fn test_range_inclusive_bincode_equivalence() {
4005 proptest!(proptest_cfg(), |(start in any::<u64>(), end in any::<u64>())| {
4006 let range = RangeInclusive::new(start, end );
4007 let wincode_serialized = serialize(&range).unwrap();
4008 let bincode_serialized = bincode::serialize(&range).unwrap();
4009 prop_assert_eq!(&wincode_serialized, &bincode_serialized);
4010
4011 let wincode_deserialized: RangeInclusive<u64> = deserialize(&wincode_serialized).unwrap();
4012 let bincode_deserialized: RangeInclusive<u64> = bincode::deserialize(&bincode_serialized).unwrap();
4013 prop_assert_eq!(range.start(), wincode_deserialized.start());
4014 prop_assert_eq!(range.end(), wincode_deserialized.end());
4015 prop_assert_eq!(wincode_deserialized.start(), bincode_deserialized.start());
4016 prop_assert_eq!(wincode_deserialized.end(), bincode_deserialized.end());
4017 });
4018 }
4019
4020 #[test]
4021 fn test_range_vec_u64() {
4022 proptest!(proptest_cfg(), |(ranges: Vec<Range<u64>>)| {
4023 let serialized = serialize(&ranges).unwrap();
4024 let bincode_serialized = bincode::serialize(&ranges).unwrap();
4025 prop_assert_eq!(&serialized, &bincode_serialized);
4026
4027 let deserialized: Vec<Range<u64>> = deserialize(&serialized).unwrap();
4028 let bincode_deserialized: Vec<Range<u64>> = bincode::deserialize(&bincode_serialized).unwrap();
4029 prop_assert_eq!(deserialized, bincode_deserialized);
4030 });
4031 }
4032
4033 #[test]
4034 fn test_range_inclusive_vec_u64() {
4035 proptest!(proptest_cfg(), |(ranges: Vec<RangeInclusive<u64>>)| {
4036 let serialized = serialize(&ranges).unwrap();
4037 let bincode_serialized = bincode::serialize(&ranges).unwrap();
4038 prop_assert_eq!(&serialized, &bincode_serialized);
4039
4040 let deserialized: Vec<RangeInclusive<u64>> = deserialize(&serialized).unwrap();
4041 let bincode_deserialized: Vec<RangeInclusive<u64>> = bincode::deserialize(&bincode_serialized).unwrap();
4042 prop_assert_eq!(deserialized, bincode_deserialized);
4043 });
4044 }
4045
4046 #[test]
4047 fn test_bound_vec_u64() {
4048 proptest!(proptest_cfg(), |(bounds: Vec<Bound<u64>>)| {
4049 let serialized = serialize(&bounds).unwrap();
4050 let bincode_serialized = bincode::serialize(&bounds).unwrap();
4051 prop_assert_eq!(&serialized, &bincode_serialized);
4052
4053 let deserialized: Vec<Bound<u64>> = deserialize(&serialized).unwrap();
4054 let bincode_deserialized: Vec<Bound<u64>> = bincode::deserialize(&bincode_serialized).unwrap();
4055 prop_assert_eq!(deserialized, bincode_deserialized);
4056 });
4057 }
4058
4059 #[test]
4060 fn test_byte_order_configuration() {
4061 let c = Configuration::default().with_big_endian();
4062 let bincode_c = bincode::DefaultOptions::new()
4063 .with_big_endian()
4064 .with_fixint_encoding();
4065
4066 proptest!(proptest_cfg(), |(value: Vec<u64>)| {
4067 let bincode_serialized = bincode_c.serialize(&value).unwrap();
4068 let serialized = config::serialize(&value, c).unwrap();
4069 prop_assert_eq!(&bincode_serialized, &serialized);
4070
4071 let deserialized: Vec<u64> = config::deserialize(&serialized, c).unwrap();
4072 let len = value.len();
4073 prop_assert_eq!(len, u64::from_be_bytes(serialized[0..8].try_into().unwrap()) as usize);
4074
4075 if !value.is_empty() {
4076 for (i, chunk) in serialized[8..].chunks(8).enumerate() {
4077 let val = u64::from_be_bytes(chunk.try_into().unwrap());
4078 prop_assert_eq!(val, value[i]);
4079 }
4080 }
4081
4082 prop_assert_eq!(value, deserialized);
4083 });
4084 }
4085
4086 #[test]
4087 fn test_duration_nanos_normalization() {
4088 use core::time::Duration;
4089
4090 proptest!(proptest_cfg(), |(secs in 0u64..u64::MAX/2, nanos in 1_000_000_000u32..=u32::MAX)| {
4091 let mut bytes: Vec<u8> = Vec::with_capacity(size_of::<u64>() + size_of::<u32>());
4092 crate::serialize_into(&mut bytes, &secs).unwrap();
4093 crate::serialize_into(&mut bytes, &nanos).unwrap();
4094
4095 let result: Duration = deserialize(&bytes).unwrap();
4096 let expected = Duration::new(secs, nanos);
4097 prop_assert_eq!(result, expected);
4098 });
4099 }
4100
4101 #[test]
4102 fn test_custom_length_encoding_and_byte_order() {
4103 let c = Configuration::default()
4104 .with_length_encoding::<FixIntLen<u32>>()
4105 .with_big_endian();
4106
4107 proptest!(proptest_cfg(), |(value: Vec<u8>)| {
4108 let serialized = config::serialize(&value, c).unwrap();
4109 let deserialized: Vec<u8> = config::deserialize(&serialized, c).unwrap();
4110 let len = value.len();
4111 prop_assert_eq!(len, u32::from_be_bytes(serialized[0..4].try_into().unwrap()) as usize);
4112 prop_assert_eq!(value, deserialized);
4113 });
4114 }
4115
4116 #[test]
4117 fn test_custom_primitive_length_encoding() {
4118 let c = Configuration::default().with_length_encoding::<u32>();
4119
4120 proptest!(proptest_cfg(), |(value: Vec<u8>)| {
4121 let serialized = config::serialize(&value, c).unwrap();
4122 let deserialized: Vec<u8> = config::deserialize(&serialized, c).unwrap();
4123 let len = value.len();
4124 prop_assert_eq!(len, u32::from_le_bytes(serialized[0..4].try_into().unwrap()) as usize);
4125 prop_assert_eq!(value, deserialized);
4126 });
4127 }
4128
4129 #[test]
4130 fn test_duration_overflow() {
4131 use core::time::Duration;
4132
4133 let mut bytes = Vec::with_capacity(size_of::<u64>() + size_of::<u32>());
4134 crate::serialize_into(&mut bytes, &u64::MAX).unwrap();
4135 crate::serialize_into(&mut bytes, &1_000_000_000u32).unwrap();
4136
4137 let result: error::ReadResult<Duration> = deserialize(&bytes);
4138 assert!(result.is_err());
4139 }
4140
4141 #[test]
4142 fn test_all_integers_with_custom_byte_order() {
4143 let c = Configuration::default().with_big_endian();
4144 let bincode_c = bincode::DefaultOptions::new()
4145 .with_big_endian()
4146 .with_fixint_encoding();
4147
4148 proptest!(proptest_cfg(), |(value: (u16, u32, u64, u128, i16, i32, i64, i128, usize, isize))| {
4149 let bincode_serialized = bincode_c.serialize(&value).unwrap();
4150 let serialized = config::serialize(&value, c).unwrap();
4151 prop_assert_eq!(&bincode_serialized, &serialized);
4152 let deserialized: (u16, u32, u64, u128, i16, i32, i64, i128, usize, isize) = config::deserialize(&serialized, c).unwrap();
4153 prop_assert_eq!(value, deserialized);
4154 });
4155 }
4156
4157 #[test]
4158 fn test_all_integers_with_varint() {
4159 let c = Configuration::default().with_varint_encoding();
4160 let bincode_c = bincode::DefaultOptions::new().with_varint_encoding();
4161
4162 proptest!(proptest_cfg(), |(value: (u16, u32, u64, u128, i16, i32, i64, i128, usize, isize))| {
4163 let bincode_serialized = bincode_c.serialize(&value).unwrap();
4164 let serialized = config::serialize(&value, c).unwrap();
4165 prop_assert_eq!(&bincode_serialized, &serialized);
4166 prop_assert_eq!(bincode_c.serialized_size(&value).unwrap(), config::serialized_size(&value, c).unwrap());
4167
4168 let deserialized: (u16, u32, u64, u128, i16, i32, i64, i128, usize, isize) = config::deserialize(&serialized, c).unwrap();
4169 prop_assert_eq!(value, deserialized);
4170 });
4171 }
4172
4173 #[test]
4174 fn test_all_integers_with_varint_big_endian() {
4175 let c = Configuration::default()
4176 .with_varint_encoding()
4177 .with_big_endian();
4178 let bincode_c = bincode::DefaultOptions::new()
4179 .with_varint_encoding()
4180 .with_big_endian();
4181
4182 proptest!(proptest_cfg(), |(value: (u16, u32, u64, u128, i16, i32, i64, i128, usize, isize))| {
4183 let bincode_serialized = bincode_c.serialize(&value).unwrap();
4184 let serialized = config::serialize(&value, c).unwrap();
4185 prop_assert_eq!(&bincode_serialized, &serialized);
4186 prop_assert_eq!(bincode_c.serialized_size(&value).unwrap(), config::serialized_size(&value, c).unwrap());
4187
4188 let deserialized: (u16, u32, u64, u128, i16, i32, i64, i128, usize, isize) = config::deserialize(&serialized, c).unwrap();
4189 prop_assert_eq!(value, deserialized);
4190 });
4191 }
4192
4193 #[test]
4194 fn test_varint_boundaries() {
4195 let c = Configuration::default().with_varint_encoding();
4196 let bincode_c = bincode::DefaultOptions::new().with_varint_encoding();
4197
4198 fn assert_varint_roundtrip<T, C, O>(val: T, c: C, bincode_c: O)
4199 where
4200 C: Config + Copy,
4201 O: Options + Copy,
4202 T: serde::Serialize
4203 + for<'de> Deserialize<'de>
4204 + PartialEq
4205 + core::fmt::Debug
4206 + SchemaWrite<C, Src = T>
4207 + for<'de> SchemaRead<'de, C, Dst = T>,
4208 {
4209 let bincode_serialized = bincode_c.serialize(&val).unwrap();
4210 let serialized = config::serialize(&val, c).unwrap();
4211 assert_eq!(bincode_serialized, serialized);
4212 assert_eq!(
4213 bincode_c.serialized_size(&val).unwrap(),
4214 config::serialized_size(&val, c).unwrap()
4215 );
4216 let deserialized: T = config::deserialize(&serialized, c).unwrap();
4217 assert_eq!(val, deserialized);
4218 }
4219
4220 for val in [0u16, 1, 250, 251, 252, u16::MAX] {
4221 assert_varint_roundtrip(val, c, bincode_c);
4222 }
4223
4224 for val in [
4225 0u32,
4226 1,
4227 250,
4228 251,
4229 252,
4230 u16::MAX as u32,
4231 u16::MAX as u32 + 1,
4232 u32::MAX,
4233 ] {
4234 assert_varint_roundtrip(val, c, bincode_c);
4235 }
4236
4237 for val in [
4238 0u64,
4239 1,
4240 250,
4241 251,
4242 252,
4243 u16::MAX as u64,
4244 u16::MAX as u64 + 1,
4245 u32::MAX as u64,
4246 u32::MAX as u64 + 1,
4247 u64::MAX,
4248 ] {
4249 assert_varint_roundtrip(val, c, bincode_c);
4250 }
4251
4252 for val in [
4253 0u128,
4254 1,
4255 250,
4256 251,
4257 252,
4258 u16::MAX as u128,
4259 u16::MAX as u128 + 1,
4260 u32::MAX as u128,
4261 u32::MAX as u128 + 1,
4262 u64::MAX as u128,
4263 u64::MAX as u128 + 1,
4264 u128::MAX,
4265 ] {
4266 assert_varint_roundtrip(val, c, bincode_c);
4267 }
4268
4269 for val in [0i16, 1, -1, 2, -2, i16::MIN, i16::MAX] {
4270 assert_varint_roundtrip(val, c, bincode_c);
4271 }
4272
4273 for val in [0i32, 1, -1, 2, -2, i32::MIN, i32::MAX] {
4274 assert_varint_roundtrip(val, c, bincode_c);
4275 }
4276
4277 for val in [0i64, 1, -1, 2, -2, i64::MIN, i64::MAX] {
4278 assert_varint_roundtrip(val, c, bincode_c);
4279 }
4280
4281 for val in [0i128, 1, -1, 2, -2, i128::MIN, i128::MAX] {
4282 assert_varint_roundtrip(val, c, bincode_c);
4283 }
4284 }
4285
4286 #[test]
4287 fn test_floats_with_custom_byte_order() {
4288 let c = Configuration::default().with_big_endian();
4289 let bincode_c = bincode::DefaultOptions::new()
4290 .with_big_endian()
4291 .with_fixint_encoding();
4292
4293 proptest!(proptest_cfg(), |(value: (f32, f64))| {
4294 let bincode_serialized = bincode_c.serialize(&value).unwrap();
4295 let serialized = config::serialize(&value, c).unwrap();
4296 prop_assert_eq!(&bincode_serialized, &serialized);
4297 let deserialized: (f32, f64) = config::deserialize(&serialized, c).unwrap();
4298 prop_assert_eq!(value, deserialized);
4299 });
4300 }
4301
4302 #[test]
4303 fn test_generic_struct() {
4304 #[derive(
4305 SchemaWrite,
4306 SchemaRead,
4307 serde::Serialize,
4308 serde::Deserialize,
4309 Debug,
4310 PartialEq,
4311 Eq,
4312 proptest_derive::Arbitrary,
4313 )]
4314 #[wincode(internal)]
4315 struct GenT<T> {
4316 inner: T,
4317 }
4318
4319 assert_eq!(
4320 <GenT<u64> as SchemaWrite<DefaultConfig>>::TYPE_META,
4321 TypeMeta::Static {
4322 size: 8,
4323 zero_copy: false
4324 }
4325 );
4326
4327 assert_eq!(
4328 <GenT<String> as SchemaWrite<DefaultConfig>>::TYPE_META,
4329 TypeMeta::Dynamic,
4330 );
4331
4332 proptest!(proptest_cfg(), |(value: GenT<u64>)| {
4333 let serialized = serialize(&value).unwrap();
4334 let bincode_serialized = bincode::serialize(&value).unwrap();
4335 prop_assert_eq!(&serialized, &bincode_serialized);
4336 let deserialized: GenT<u64> = deserialize(&serialized).unwrap();
4337 let bincode_deserialized: GenT<u64> = bincode::deserialize(&bincode_serialized).unwrap();
4338 prop_assert_eq!(&deserialized, &bincode_deserialized);
4339 prop_assert_eq!(value, deserialized);
4340 });
4341 }
4342
4343 #[test]
4344 fn test_generic_struct_two_params() {
4345 #[derive(
4346 SchemaWrite,
4347 SchemaRead,
4348 serde::Serialize,
4349 serde::Deserialize,
4350 Debug,
4351 PartialEq,
4352 Eq,
4353 proptest_derive::Arbitrary,
4354 )]
4355 #[wincode(internal)]
4356 struct GenT<T, U> {
4357 t: T,
4358 u: U,
4359 }
4360
4361 assert_eq!(
4362 <GenT<u64, u64> as SchemaWrite<DefaultConfig>>::TYPE_META,
4363 TypeMeta::Static {
4364 size: 16,
4365 zero_copy: false
4366 }
4367 );
4368
4369 assert_eq!(
4370 <GenT<String, u64> as SchemaWrite<DefaultConfig>>::TYPE_META,
4371 TypeMeta::Dynamic,
4372 );
4373
4374 proptest!(proptest_cfg(), |(value: GenT<u64, u64>)| {
4375 let serialized = serialize(&value).unwrap();
4376 let bincode_serialized = bincode::serialize(&value).unwrap();
4377 prop_assert_eq!(&serialized, &bincode_serialized);
4378 let deserialized: GenT<u64, u64> = deserialize(&serialized).unwrap();
4379 let bincode_deserialized: GenT<u64, u64> = bincode::deserialize(&bincode_serialized).unwrap();
4380 prop_assert_eq!(&deserialized, &bincode_deserialized);
4381 prop_assert_eq!(value, deserialized);
4382 });
4383 }
4384
4385 #[test]
4386 fn test_generic_struct_repr_transparent() {
4387 #[derive(
4388 SchemaWrite,
4389 SchemaRead,
4390 serde::Serialize,
4391 serde::Deserialize,
4392 Debug,
4393 PartialEq,
4394 Eq,
4395 proptest_derive::Arbitrary,
4396 )]
4397 #[wincode(internal)]
4398 #[repr(transparent)]
4399 struct GenT<T> {
4400 inner: T,
4401 }
4402
4403 assert_eq!(
4404 <GenT<u64> as SchemaWrite<DefaultConfig>>::TYPE_META,
4405 TypeMeta::Static {
4406 size: 8,
4407 zero_copy: true
4408 }
4409 );
4410
4411 proptest!(proptest_cfg(), |(value: GenT<u64>)| {
4412 let serialized = serialize(&value).unwrap();
4413 let bincode_serialized = bincode::serialize(&value).unwrap();
4414 prop_assert_eq!(&serialized, &bincode_serialized);
4415 let deserialized: GenT<u64> = deserialize(&serialized).unwrap();
4416 let bincode_deserialized: GenT<u64> = bincode::deserialize(&bincode_serialized).unwrap();
4417 prop_assert_eq!(&deserialized, &bincode_deserialized);
4418 prop_assert_eq!(value, deserialized);
4419 });
4420 }
4421
4422 #[test]
4423 fn test_generic_struct_with_existing_bound() {
4424 #[derive(
4425 SchemaWrite,
4426 SchemaRead,
4427 serde::Serialize,
4428 serde::Deserialize,
4429 Debug,
4430 PartialEq,
4431 Eq,
4432 proptest_derive::Arbitrary,
4433 )]
4434 #[wincode(internal)]
4435 #[repr(transparent)]
4436 struct GenT<T: Copy> {
4437 inner: T,
4438 }
4439
4440 proptest!(proptest_cfg(), |(value: GenT<u64>)| {
4441 let serialized = serialize(&value).unwrap();
4442 let bincode_serialized = bincode::serialize(&value).unwrap();
4443 prop_assert_eq!(&serialized, &bincode_serialized);
4444 let deserialized: GenT<u64> = deserialize(&serialized).unwrap();
4445 let bincode_deserialized: GenT<u64> = bincode::deserialize(&bincode_serialized).unwrap();
4446 prop_assert_eq!(&deserialized, &bincode_deserialized);
4447 prop_assert_eq!(value, deserialized);
4448 });
4449 }
4450
4451 #[test]
4452 fn test_generic_enum() {
4453 #[derive(
4454 SchemaWrite,
4455 SchemaRead,
4456 serde::Serialize,
4457 serde::Deserialize,
4458 Debug,
4459 PartialEq,
4460 Eq,
4461 proptest_derive::Arbitrary,
4462 )]
4463 #[wincode(internal)]
4464 enum GenT<T> {
4465 A(T),
4466 B(u8),
4467 }
4468
4469 assert_eq!(
4470 <GenT<u8> as SchemaWrite<DefaultConfig>>::TYPE_META,
4471 TypeMeta::Static {
4472 size: size_of::<u32>() + 1,
4473 zero_copy: false
4474 }
4475 );
4476
4477 assert_eq!(
4478 <GenT<u64> as SchemaWrite<DefaultConfig>>::TYPE_META,
4479 TypeMeta::Dynamic,
4480 );
4481
4482 proptest!(proptest_cfg(), |(value: GenT<u64>)| {
4483 let serialized = serialize(&value).unwrap();
4484 let bincode_serialized = bincode::serialize(&value).unwrap();
4485 prop_assert_eq!(&serialized, &bincode_serialized);
4486 let deserialized: GenT<u64> = deserialize(&serialized).unwrap();
4487 let bincode_deserialized: GenT<u64> = bincode::deserialize(&bincode_serialized).unwrap();
4488 prop_assert_eq!(&deserialized, &bincode_deserialized);
4489 prop_assert_eq!(value, deserialized);
4490 });
4491 }
4492
4493 #[test]
4494 fn test_recursive_type() {
4495 #[derive(
4496 SchemaWrite, SchemaRead, PartialEq, Debug, serde::Serialize, serde::Deserialize,
4497 )]
4498 #[wincode(internal)]
4499 pub enum Value {
4500 Usize(usize),
4501 List(Vec<Value>),
4502 }
4503
4504 let val = Value::List(vec![Value::Usize(0), Value::List(vec![Value::Usize(1)])]);
4505 let bincode_serialized = bincode::serialize(&val).unwrap();
4506 let serialized = serialize(&val).unwrap();
4507 assert_eq!(&bincode_serialized, &serialized);
4508
4509 let deserialized: Value = deserialize(&serialized).unwrap();
4510 let bincode_deserialized: Value = bincode::deserialize(&bincode_serialized).unwrap();
4511 assert_eq!(&val, &bincode_deserialized);
4512 assert_eq!(val, deserialized);
4513 }
4514
4515 #[test]
4516 fn test_cow_str() {
4517 proptest!(proptest_cfg(), |(value: Cow<str>)| {
4518 let serialized = serialize(&value).unwrap();
4519 let bincode_serialized = bincode::serialize(&value).unwrap();
4520 prop_assert_eq!(&serialized, &bincode_serialized);
4521 let deserialized: Cow<str> = deserialize(&serialized).unwrap();
4522 let bincode_deserialized: Cow<str> = bincode::deserialize(&bincode_serialized).unwrap();
4523 prop_assert_eq!(&deserialized, &bincode_deserialized);
4524 prop_assert_eq!(value, deserialized);
4525 });
4526 }
4527
4528 #[test]
4529 fn test_cow_bytes() {
4530 proptest!(proptest_cfg(), |(value: Cow<[u8]>)| {
4531 let serialized = serialize(&value).unwrap();
4532 let bincode_serialized = bincode::serialize(&value).unwrap();
4533 prop_assert_eq!(&serialized, &bincode_serialized);
4534 let deserialized: Cow<[u8]> = deserialize(&serialized).unwrap();
4535 let bincode_deserialized: Cow<[u8]> = bincode::deserialize(&bincode_serialized).unwrap();
4536 prop_assert_eq!(&deserialized, &bincode_deserialized);
4537 prop_assert_eq!(value, deserialized);
4538 });
4539 }
4540
4541 #[test]
4542 fn test_cow_bytes_owned() {
4543 proptest!(proptest_cfg(), |(value: Cow<[u8]>)| {
4544 let serialized = serialize(&value).unwrap();
4545 let bincode_serialized = bincode::serialize(&value).unwrap();
4546 prop_assert_eq!(&serialized, &bincode_serialized);
4547 let deserialized = <Cow<[u8]> as SchemaRead<DefaultConfig>>
4548 ::get(NoBorrowReader::new(&serialized)).unwrap();
4549 let bincode_deserialized: Cow<[u8]> = bincode::deserialize_from(bincode_serialized.as_slice()).unwrap();
4550 prop_assert_eq!(&deserialized, &bincode_deserialized);
4551 prop_assert_eq!(value, deserialized);
4552 });
4553 }
4554
4555 #[test]
4556 fn test_cow_str_owned() {
4557 proptest!(proptest_cfg(), |(value: Cow<str>)| {
4558 let serialized = serialize(&value).unwrap();
4559 let bincode_serialized = bincode::serialize(&value).unwrap();
4560 prop_assert_eq!(&serialized, &bincode_serialized);
4561 let deserialized = <Cow<str> as SchemaRead<DefaultConfig>>
4562 ::get(NoBorrowReader::new(&serialized)).unwrap();
4563 let bincode_deserialized: Cow<str> = bincode::deserialize_from(bincode_serialized.as_slice()).unwrap();
4564 prop_assert_eq!(&deserialized, &bincode_deserialized);
4565 prop_assert_eq!(value, deserialized);
4566 });
4567 }
4568
4569 #[test]
4570 fn test_cow_ctx() {
4571 #[derive(Debug, PartialEq)]
4572 struct MaybeBorrowed<'a> {
4573 len: u8,
4574 data: Cow<'a, [u8]>,
4575 }
4576
4577 unsafe impl<'a, C: ConfigCore> SchemaWrite<C> for MaybeBorrowed<'a> {
4578 type Src = Self;
4579
4580 fn size_of(src: &Self::Src) -> WriteResult<usize> {
4581 Ok(1 + src.data.len())
4582 }
4583
4584 fn write(mut writer: impl Writer, src: &Self::Src) -> WriteResult<()> {
4585 writer.write(&[src.data.len() as u8])?;
4586 writer.write(&src.data)?;
4587 Ok(())
4588 }
4589 }
4590
4591 unsafe impl<'de, C: ConfigCore> SchemaRead<'de, C> for MaybeBorrowed<'de> {
4592 type Dst = Self;
4593
4594 fn read(
4595 mut reader: impl Reader<'de>,
4596 dst: &mut MaybeUninit<Self::Dst>,
4597 ) -> ReadResult<()> {
4598 let len = reader.take_byte()?;
4599 let cow = <Cow<'de, [u8]> as SchemaReadContext<C, _>>::get_with_context(
4600 context::Len(len as usize),
4601 reader,
4602 )?;
4603 dst.write(MaybeBorrowed { len, data: cow });
4604 Ok(())
4605 }
4606 }
4607
4608 proptest!(proptest_cfg(), |(value in proptest::collection::vec(any::<u8>(), 0..=64))| {
4609 let value = MaybeBorrowed {
4610 len: value.len() as u8,
4611 data: Cow::Owned(value),
4612 };
4613
4614 let serialized = serialize(&value).unwrap();
4615
4616 let deserialized = <MaybeBorrowed as SchemaRead<DefaultConfig>>
4617 ::get(NoBorrowReader::new(&serialized)).unwrap();
4618 prop_assert!(matches!(deserialized.data, Cow::Owned(_)));
4619 prop_assert_eq!(&value, &deserialized);
4620
4621 let deserialized: MaybeBorrowed = deserialize(&serialized).unwrap();
4622 prop_assert!(matches!(deserialized.data, Cow::Borrowed(_)));
4623 prop_assert_eq!(value, deserialized);
4624 });
4625 }
4626}