1 #![allow(clippy::uninlined_format_args)]
2 #![allow(unused_imports)]
3 //! The integration tests seem to always have `std` linked, so things that would
4 //! depend on that can go here.
5 
6 use bytemuck::*;
7 use core::num::NonZeroU8;
8 
9 #[test]
test_transparent_vtabled()10 fn test_transparent_vtabled() {
11   use core::fmt::Display;
12 
13   #[repr(transparent)]
14   struct DisplayTraitObj(dyn Display);
15 
16   unsafe impl TransparentWrapper<dyn Display> for DisplayTraitObj {}
17 
18   impl Display for DisplayTraitObj {
19     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
20       self.0.fmt(f)
21     }
22   }
23 
24   let v = DisplayTraitObj::wrap_ref(&5i32);
25   let s = format!("{}", v);
26   assert_eq!(s, "5");
27 
28   let mut x = 100i32;
29   let v_mut = DisplayTraitObj::wrap_mut(&mut x);
30   let s = format!("{}", v_mut);
31   assert_eq!(s, "100");
32 }
33 
34 #[test]
35 #[cfg(feature = "extern_crate_alloc")]
test_large_box_alloc()36 fn test_large_box_alloc() {
37   type SuperPage = [[u8; 4096]; 4096];
38   let _: Box<SuperPage> = try_zeroed_box().unwrap();
39 }
40 
41 #[test]
42 #[cfg(feature = "extern_crate_alloc")]
test_zero_sized_box_alloc()43 fn test_zero_sized_box_alloc() {
44   #[repr(align(4096))]
45   struct Empty;
46   unsafe impl Zeroable for Empty {}
47   let _: Box<Empty> = try_zeroed_box().unwrap();
48 }
49 
50 #[test]
51 #[cfg(feature = "extern_crate_alloc")]
test_try_from_box_bytes()52 fn test_try_from_box_bytes() {
53   // Different layout: target alignment is greater than source alignment.
54   assert_eq!(
55     try_from_box_bytes::<u32>(Box::new([0u8; 4]).into()).map_err(|(x, _)| x),
56     Err(PodCastError::AlignmentMismatch)
57   );
58 
59   // Different layout: target alignment is less than source alignment.
60   assert_eq!(
61     try_from_box_bytes::<u32>(Box::new(0u64).into()).map_err(|(x, _)| x),
62     Err(PodCastError::AlignmentMismatch)
63   );
64 
65   // Different layout: target size is greater than source size.
66   assert_eq!(
67     try_from_box_bytes::<[u32; 2]>(Box::new(0u32).into()).map_err(|(x, _)| x),
68     Err(PodCastError::SizeMismatch)
69   );
70 
71   // Different layout: target size is less than source size.
72   assert_eq!(
73     try_from_box_bytes::<u32>(Box::new([0u32; 2]).into()).map_err(|(x, _)| x),
74     Err(PodCastError::SizeMismatch)
75   );
76 
77   // Round trip: alignment is equal to size.
78   assert_eq!(*from_box_bytes::<u32>(Box::new(1000u32).into()), 1000u32);
79 
80   // Round trip: alignment is divider of size.
81   assert_eq!(&*from_box_bytes::<[u8; 5]>(Box::new(*b"hello").into()), b"hello");
82 
83   // It's ok for T to have uninitialized bytes.
84   #[cfg(feature = "derive")]
85   {
86     #[derive(Debug, Copy, Clone, PartialEq, Eq, AnyBitPattern)]
87     struct Foo(u8, u16);
88     assert_eq!(
89       *from_box_bytes::<Foo>(Box::new([0xc5c5u16; 2]).into()),
90       Foo(0xc5u8, 0xc5c5u16)
91     );
92   }
93 }
94 
95 #[test]
96 #[cfg(feature = "extern_crate_alloc")]
test_box_bytes_of()97 fn test_box_bytes_of() {
98   assert_eq!(&*box_bytes_of(Box::new(*b"hello")), b"hello");
99 
100   #[cfg(target_endian = "big")]
101   assert_eq!(&*box_bytes_of(Box::new(0x12345678)), b"\x12\x34\x56\x78");
102   #[cfg(target_endian = "little")]
103   assert_eq!(&*box_bytes_of(Box::new(0x12345678)), b"\x78\x56\x34\x12");
104 
105   // It's ok for T to have invalid bit patterns.
106   assert_eq!(&*box_bytes_of(Box::new(NonZeroU8::new(0xc5))), b"\xc5");
107 }
108