1#![allow(clippy::size_of_in_element_count)] #![warn(clippy::pedantic)]
3#![cfg_attr(not(feature = "std"), no_std)]
4
5#[cfg(feature = "glam")]
8use glam::{
9 DMat2, DMat3, DMat4, DQuat, DVec2, DVec3, DVec4, IVec2, IVec3, IVec4, Mat2, Mat3, Mat4, Quat,
10 UVec2, UVec3, UVec4, Vec2, Vec3, Vec4,
11};
12#[cfg(feature = "half")]
13use half::{bf16, f16};
14
15#[derive(Debug)]
16pub enum Error {
17 Size,
18}
19
20#[cfg(feature = "std")]
21impl std::error::Error for Error {}
22impl core::fmt::Display for Error {
23 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
24 match self {
25 Error::Size => write!(f, ""),
26 }
27 }
28}
29
30pub type Result<T, E = Error> = core::result::Result<T, E>;
31
32pub unsafe trait Pod {
35 fn as_bytes(&self) -> &[u8];
36 fn as_bytes_mut(&mut self) -> &mut [u8];
37 fn from_bytes(bytes: &[u8]) -> Result<&Self>
40 where
41 Self: Sized,
42 {
43 if bytes.len() == core::mem::size_of::<Self>() {
44 Ok(unsafe { Self::from_bytes_unchecked(bytes) })
45 } else {
46 Err(Error::Size)
47 }
48 }
49 unsafe fn from_bytes_unchecked(bytes: &[u8]) -> &Self
52 where
53 Self: Sized,
54 {
55 &*bytes.as_ptr().cast::<Self>()
56 }
57 fn from_bytes_mut(bytes: &mut [u8]) -> Result<&mut Self>
60 where
61 Self: Sized,
62 {
63 if bytes.len() == core::mem::size_of::<Self>() {
64 Ok(unsafe { Self::from_bytes_mut_unchecked(bytes) })
65 } else {
66 Err(Error::Size)
67 }
68 }
69
70 unsafe fn from_bytes_mut_unchecked(bytes: &mut [u8]) -> &mut Self
73 where
74 Self: Sized,
75 {
76 &mut *bytes.as_mut_ptr().cast::<Self>()
77 }
78}
79
80macro_rules! impl_pod {
81 ($($ty:ty)+) => {
82 $(
83 unsafe impl Pod for $ty {
85 fn as_bytes(&self) -> &[u8] {
86 unsafe { &*(self as *const $ty).cast::<[u8; 4]>() }
87 }
88 fn as_bytes_mut(&mut self) -> &mut [u8] {
89 unsafe { &mut*(self as *mut $ty).cast::<[u8; 4]>() }
90 }
91 }
92 unsafe impl<const N: usize> Pod for [$ty; N] {
95 fn as_bytes(&self) -> &[u8] {
96 unsafe {
97 core::slice::from_raw_parts(
98 self.as_ptr().cast(),
99 self.len() * core::mem::size_of::<$ty>(),
100 )
101 }
102 }
103 fn as_bytes_mut(&mut self) -> &mut [u8] {
104 unsafe {
105 core::slice::from_raw_parts_mut(
106 self.as_mut_ptr().cast(),
107 self.len() * core::mem::size_of::<$ty>(),
108 )
109 }
110 }
111 }
112 )*
113 }
114}
115
116impl_pod!(u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize f32 f64);
118#[cfg(feature = "half")]
119impl_pod!(f16 bf16);
120#[cfg(feature = "glam")]
122impl_pod!(DMat2 DMat3 DMat4 DQuat DVec2 DVec3 DVec4 IVec2 IVec3 IVec4 Mat2 Mat3 Mat4 Quat UVec2 UVec3 UVec4 Vec2 Vec3 Vec4);