Skip to main content

dunge_shade/
bytes.rs

1use {
2    glam::{IVec2, IVec3, IVec4, Mat2, Mat3, Mat4, UVec2, UVec3, UVec4, Vec2, Vec3, Vec4},
3    std::slice,
4};
5
6/// Get bytes of a value.
7///
8/// You shouldn't implement this trait manually, use `derive` macro.
9///
10/// # Safety
11///
12/// It should be safe to cast a slice of `Self` to bytes.
13pub unsafe trait Bytes: Sized + Copy + 'static {}
14
15pub const fn bytes_size<B>() -> usize
16where
17    B: Bytes,
18{
19    size_of::<B>()
20}
21
22pub const fn as_bytes<B>(slice: &[B]) -> &[u8]
23where
24    B: Bytes,
25{
26    // SAFETY:
27    // The invariant of `Bytes` is it's safe to get bytes of the values
28    unsafe {
29        let bytelen = slice.len() * bytes_size::<B>();
30        let data = slice.as_ptr().cast();
31        slice::from_raw_parts(data, bytelen)
32    }
33}
34
35unsafe impl Bytes for bool {}
36unsafe impl Bytes for u8 {}
37unsafe impl Bytes for f32 {}
38unsafe impl Bytes for u32 {}
39unsafe impl Bytes for i32 {}
40unsafe impl<B, const N: usize> Bytes for [B; N] where B: Bytes {}
41
42unsafe impl Bytes for Vec2 {}
43unsafe impl Bytes for Vec3 {}
44unsafe impl Bytes for Vec4 {}
45unsafe impl Bytes for UVec2 {}
46unsafe impl Bytes for UVec3 {}
47unsafe impl Bytes for UVec4 {}
48unsafe impl Bytes for IVec2 {}
49unsafe impl Bytes for IVec3 {}
50unsafe impl Bytes for IVec4 {}
51unsafe impl Bytes for Mat2 {}
52unsafe impl Bytes for Mat3 {}
53unsafe impl Bytes for Mat4 {}