1 #![allow(clippy::disallowed_names)]
2 use bytemuck::{offset_of, Zeroable};
3 
4 #[test]
test_offset_of_vertex()5 fn test_offset_of_vertex() {
6   #[repr(C)]
7   struct Vertex {
8     pos: [f32; 2],
9     uv: [u16; 2],
10     color: [u8; 4],
11   }
12   unsafe impl Zeroable for Vertex {}
13 
14   let pos = offset_of!(Zeroable::zeroed(), Vertex, pos);
15   let uv = offset_of!(Zeroable::zeroed(), Vertex, uv);
16   let color = offset_of!(Zeroable::zeroed(), Vertex, color);
17 
18   assert_eq!(pos, 0);
19   assert_eq!(uv, 8);
20   assert_eq!(color, 12);
21 }
22 
23 #[test]
test_offset_of_foo()24 fn test_offset_of_foo() {
25   #[derive(Default)]
26   struct Foo {
27     a: u8,
28     b: &'static str,
29     c: i32,
30   }
31 
32   let a_offset = offset_of!(Default::default(), Foo, a);
33   let b_offset = offset_of!(Default::default(), Foo, b);
34   let c_offset = offset_of!(Default::default(), Foo, c);
35 
36   assert_ne!(a_offset, b_offset);
37   assert_ne!(b_offset, c_offset);
38   // We can't check against hardcoded values for a repr(Rust) type,
39   // but prove to ourself this way.
40 
41   let foo = Foo::default();
42   // Note: offsets are in bytes.
43   let as_bytes = &foo as *const _ as *const u8;
44 
45   // we're using wrapping_offset here because it's not worth
46   // the unsafe block, but it would be valid to use `add` instead,
47   // as it cannot overflow.
48   assert_eq!(
49     &foo.a as *const _ as usize,
50     as_bytes.wrapping_add(a_offset) as usize
51   );
52   assert_eq!(
53     &foo.b as *const _ as usize,
54     as_bytes.wrapping_add(b_offset) as usize
55   );
56   assert_eq!(
57     &foo.c as *const _ as usize,
58     as_bytes.wrapping_add(c_offset) as usize
59   );
60 }
61