1use bytemuck::{Pod, Zeroable};
2
3#[derive(Debug, Clone, Copy, PartialEq)]
8#[repr(C)]
9pub struct Position3<T: Copy> {
10 pub coords: [T; 3],
11}
12
13unsafe impl Zeroable for Position3<f32> {}
15unsafe impl Pod for Position3<f32> {}
16
17unsafe impl Zeroable for Position3<f64> {}
18unsafe impl Pod for Position3<f64> {}
19
20unsafe impl Zeroable for Position3<half::f16> {}
21unsafe impl Pod for Position3<half::f16> {}
22
23impl<T: Copy> Position3<T> {
24 pub fn new(x: T, y: T, z: T) -> Self {
25 Self { coords: [x, y, z] }
26 }
27}
28
29impl<T: Copy> From<[T; 3]> for Position3<T> {
30 fn from(coords: [T; 3]) -> Self {
31 Self { coords }
32 }
33}
34
35impl<T: Copy> From<Position3<T>> for [T; 3] {
36 fn from(p: Position3<T>) -> Self {
37 p.coords
38 }
39}
40
41#[cfg(test)]
42mod tests {
43 use super::*;
44
45 #[test]
46 fn position3_size_and_alignment() {
47 assert_eq!(std::mem::size_of::<Position3<f32>>(), 12);
48 assert_eq!(std::mem::align_of::<Position3<f32>>(), 4);
49
50 assert_eq!(std::mem::size_of::<Position3<f64>>(), 24);
51
52 assert_eq!(std::mem::size_of::<Position3<half::f16>>(), 6);
53 }
54
55 #[test]
56 fn position3_bytemuck_cast() {
57 let positions = vec![
58 Position3::new(1.0f32, 2.0, 3.0),
59 Position3::new(4.0f32, 5.0, 6.0),
60 ];
61 let bytes: &[u8] = bytemuck::cast_slice(&positions);
62 assert_eq!(bytes.len(), 24);
63
64 let back: &[Position3<f32>] = bytemuck::cast_slice(bytes);
65 assert_eq!(back[0].coords, [1.0, 2.0, 3.0]);
66 assert_eq!(back[1].coords, [4.0, 5.0, 6.0]);
67 }
68}