1 #[cfg(feature = "bytecheck")] 2 macro_rules! impl_rkyv { 3 (@bytecheck $type:ty) => { 4 // SAFETY: All bit patterns are valid for these primitive types. 5 // https://docs.rs/bytecheck/0.8.1/src/bytecheck/lib.rs.html#352 6 unsafe impl<C: Fallible +?Sized> rkyv::bytecheck::CheckBytes<C> for $type { 7 #[inline] 8 unsafe fn check_bytes( 9 _value: *const Self, 10 _: &mut C, 11 ) -> Result<(), C::Error> { 12 Ok(()) 13 } 14 } 15 }; 16 17 ($type:ty) => { 18 impl_rkyv_derive!(@serialize $type); 19 impl_rkyv_derive!(@archive_deserialize $type); 20 impl_rkyv!(@bytecheck $type); 21 }; 22 } 23 24 #[cfg(not(feature = "bytecheck"))] 25 macro_rules! impl_rkyv { 26 ($type:ty) => { 27 impl_rkyv_derive!(@serialize $type); 28 impl_rkyv_derive!(@archive_deserialize $type); 29 }; 30 } 31 32 macro_rules! impl_rkyv_derive { 33 (@serialize $type:ty) => { 34 impl<S: Fallible + ?Sized> Serialize<S> for $type { 35 #[inline] 36 fn serialize(&self, _: &mut S) -> Result<Self::Resolver, S::Error> { 37 Ok(()) 38 } 39 } 40 }; 41 42 (@archive_deserialize $type:ty) => { 43 // SAFETY: All glam types have a fully defined data layout. 44 unsafe impl rkyv::traits::NoUndef for $type {} 45 // SAFETY: All glam types have a stable, well-defined layout that is identical on all 46 // targets. 47 unsafe impl rkyv::Portable for $type {} 48 impl Archive for $type { 49 type Archived = $type; 50 type Resolver = (); 51 52 #[inline] 53 fn resolve(&self, _: Self::Resolver, out: Place<Self::Archived>) { 54 out.write(*self) 55 } 56 } 57 58 impl<D: Fallible + ?Sized> Deserialize<$type, D> for $type { 59 #[inline] 60 fn deserialize(&self, _: &mut D) -> Result<$type, D::Error> { 61 Ok(*self) 62 } 63 } 64 }; 65 } 66 67 mod f32 { 68 use crate::{Affine2, Affine3A, Mat2, Mat3, Mat3A, Mat4, Quat, Vec2, Vec3, Vec3A, Vec4}; 69 use rkyv::{rancor::Fallible, Archive, Deserialize, Place, Serialize}; 70 impl_rkyv!(Affine2); 71 impl_rkyv!(Affine3A); 72 impl_rkyv!(Mat2); 73 impl_rkyv!(Mat3); 74 impl_rkyv!(Mat3A); 75 impl_rkyv!(Mat4); 76 impl_rkyv!(Quat); 77 impl_rkyv!(Vec2); 78 impl_rkyv!(Vec3); 79 impl_rkyv!(Vec3A); 80 impl_rkyv!(Vec4); 81 } 82 83 mod f64 { 84 use crate::{DAffine2, DAffine3, DMat2, DMat3, DMat4, DQuat, DVec2, DVec3, DVec4}; 85 use rkyv::{rancor::Fallible, Archive, Deserialize, Place, Serialize}; 86 87 impl_rkyv!(DAffine2); 88 impl_rkyv!(DAffine3); 89 impl_rkyv!(DMat2); 90 impl_rkyv!(DMat3); 91 impl_rkyv!(DMat4); 92 impl_rkyv!(DQuat); 93 impl_rkyv!(DVec2); 94 impl_rkyv!(DVec3); 95 impl_rkyv!(DVec4); 96 } 97 98 mod i8 { 99 use crate::{I8Vec2, I8Vec3, I8Vec4}; 100 use rkyv::{rancor::Fallible, Archive, Deserialize, Place, Serialize}; 101 102 impl_rkyv!(I8Vec2); 103 impl_rkyv!(I8Vec3); 104 impl_rkyv!(I8Vec4); 105 } 106 107 mod i16 { 108 use crate::{I16Vec2, I16Vec3, I16Vec4}; 109 use rkyv::{rancor::Fallible, Archive, Deserialize, Place, Serialize}; 110 111 impl_rkyv!(I16Vec2); 112 impl_rkyv!(I16Vec3); 113 impl_rkyv!(I16Vec4); 114 } 115 116 mod i32 { 117 use crate::{IVec2, IVec3, IVec4}; 118 use rkyv::{rancor::Fallible, Archive, Deserialize, Place, Serialize}; 119 120 impl_rkyv!(IVec2); 121 impl_rkyv!(IVec3); 122 impl_rkyv!(IVec4); 123 } 124 125 mod i64 { 126 use crate::{I64Vec2, I64Vec3, I64Vec4}; 127 use rkyv::{rancor::Fallible, Archive, Deserialize, Place, Serialize}; 128 129 impl_rkyv!(I64Vec2); 130 impl_rkyv!(I64Vec3); 131 impl_rkyv!(I64Vec4); 132 } 133 134 mod u8 { 135 use crate::{U8Vec2, U8Vec3, U8Vec4}; 136 use rkyv::{rancor::Fallible, Archive, Deserialize, Place, Serialize}; 137 138 impl_rkyv!(U8Vec2); 139 impl_rkyv!(U8Vec3); 140 impl_rkyv!(U8Vec4); 141 } 142 143 mod u16 { 144 use crate::{U16Vec2, U16Vec3, U16Vec4}; 145 use rkyv::{rancor::Fallible, Archive, Deserialize, Place, Serialize}; 146 147 impl_rkyv!(U16Vec2); 148 impl_rkyv!(U16Vec3); 149 impl_rkyv!(U16Vec4); 150 } 151 152 mod u32 { 153 use crate::{UVec2, UVec3, UVec4}; 154 use rkyv::{rancor::Fallible, Archive, Deserialize, Place, Serialize}; 155 156 impl_rkyv!(UVec2); 157 impl_rkyv!(UVec3); 158 impl_rkyv!(UVec4); 159 } 160 161 mod u64 { 162 use crate::{U64Vec2, U64Vec3, U64Vec4}; 163 use rkyv::{rancor::Fallible, Archive, Deserialize, Place, Serialize}; 164 165 impl_rkyv!(U64Vec2); 166 impl_rkyv!(U64Vec3); 167 impl_rkyv!(U64Vec4); 168 } 169 170 #[cfg(test)] 171 mod test { 172 /// The serializer type expected by [`rkyv::to_bytes()`]. 173 pub type TestSerializer<'a> = rkyv::api::high::HighSerializer< 174 rkyv::util::AlignedVec, 175 rkyv::ser::allocator::ArenaHandle<'a>, 176 rkyv::rancor::Panic, 177 >; 178 /// The deserializer type expected by [`rkyv::deserialize()`]. 179 pub type TestDeserializer = rkyv::api::high::HighDeserializer<rkyv::rancor::Panic>; test_archive<T>(value: &T) where T: core::fmt::Debug + PartialEq + rkyv::Portable + for<'a> rkyv::Serialize<TestSerializer<'a>>, T::Archived: core::fmt::Debug + PartialEq<T> + rkyv::Deserialize<T, TestDeserializer>,180 pub fn test_archive<T>(value: &T) 181 where 182 T: core::fmt::Debug 183 + PartialEq 184 + rkyv::Portable 185 + for<'a> rkyv::Serialize<TestSerializer<'a>>, 186 T::Archived: core::fmt::Debug + PartialEq<T> + rkyv::Deserialize<T, TestDeserializer>, 187 { 188 let buffer = rkyv::to_bytes(value).unwrap(); 189 190 // SAFETY: all bit patterns are valid for the primitive types used by glam. There is 191 // no need to write special-cased conditional tests that rely on bytecheck for the safe 192 // rkyv::access() wrapper. 193 let archived_value = unsafe { rkyv::access_unchecked::<T::Archived>(&buffer) }; 194 assert_eq!(archived_value, value); 195 assert_eq!( 196 &rkyv::deserialize::<T, rkyv::rancor::Panic>(archived_value).unwrap(), 197 value 198 ); 199 } 200 201 #[test] test_rkyv()202 fn test_rkyv() { 203 use crate::{Affine2, Affine3A, Mat2, Mat3, Mat3A, Mat4, Quat, Vec2, Vec3, Vec3A, Vec4}; 204 test_archive(&Affine2::from_cols_array(&[1.0, 0.0, 2.0, 0.0, 3.0, 4.0])); 205 test_archive(&Affine3A::from_cols_array(&[ 206 1.0, 0.0, 0.0, 0.0, 2.0, 0.0, 0.0, 0.0, 3.0, 4.0, 5.0, 6.0, 207 ])); 208 test_archive(&Mat2::from_cols_array(&[1.0, 2.0, 3.0, 4.0])); 209 test_archive(&Mat3::from_cols_array(&[ 210 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 211 ])); 212 test_archive(&Mat3A::from_cols_array(&[ 213 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 214 ])); 215 test_archive(&Mat4::from_cols_array(&[ 216 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 217 ])); 218 test_archive(&Quat::from_xyzw(1.0, 2.0, 3.0, 4.0)); 219 test_archive(&Vec2::new(1.0, 2.0)); 220 test_archive(&Vec3::new(1.0, 2.0, 3.0)); 221 test_archive(&Vec3A::new(1.0, 2.0, 3.0)); 222 test_archive(&Vec4::new(1.0, 2.0, 3.0, 4.0)); 223 224 use crate::{DAffine2, DAffine3, DMat2, DMat3, DMat4, DQuat, DVec2, DVec3, DVec4}; 225 test_archive(&DAffine2::from_cols_array(&[1.0, 0.0, 2.0, 0.0, 3.0, 4.0])); 226 test_archive(&DAffine3::from_cols_array(&[ 227 1.0, 0.0, 0.0, 0.0, 2.0, 0.0, 0.0, 0.0, 3.0, 4.0, 5.0, 6.0, 228 ])); 229 test_archive(&DMat2::from_cols_array(&[1.0, 2.0, 3.0, 4.0])); 230 test_archive(&DMat3::from_cols_array(&[ 231 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 232 ])); 233 test_archive(&DMat4::from_cols_array(&[ 234 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 235 ])); 236 test_archive(&DQuat::from_xyzw(1.0, 2.0, 3.0, 4.0)); 237 test_archive(&DVec2::new(1.0, 2.0)); 238 test_archive(&DVec3::new(1.0, 2.0, 3.0)); 239 test_archive(&DVec4::new(1.0, 2.0, 3.0, 4.0)); 240 241 use crate::{I8Vec2, I8Vec3, I8Vec4}; 242 test_archive(&I8Vec2::new(-1, 2)); 243 test_archive(&I8Vec3::new(-1, 2, 3)); 244 test_archive(&I8Vec4::new(-1, 2, 3, 4)); 245 246 use crate::{I16Vec2, I16Vec3, I16Vec4}; 247 test_archive(&I16Vec2::new(-1, 2)); 248 test_archive(&I16Vec3::new(-1, 2, 3)); 249 test_archive(&I16Vec4::new(-1, 2, 3, 4)); 250 251 use crate::{IVec2, IVec3, IVec4}; 252 test_archive(&IVec2::new(-1, 2)); 253 test_archive(&IVec3::new(-1, 2, 3)); 254 test_archive(&IVec4::new(-1, 2, 3, 4)); 255 256 use crate::{I64Vec2, I64Vec3, I64Vec4}; 257 test_archive(&I64Vec2::new(-1, 2)); 258 test_archive(&I64Vec3::new(-1, 2, 3)); 259 test_archive(&I64Vec4::new(-1, 2, 3, 4)); 260 261 use crate::{U8Vec2, U8Vec3, U8Vec4}; 262 test_archive(&U8Vec2::new(1, 2)); 263 test_archive(&U8Vec3::new(1, 2, 3)); 264 test_archive(&U8Vec4::new(1, 2, 3, 4)); 265 266 use crate::{U16Vec2, U16Vec3, U16Vec4}; 267 test_archive(&U16Vec2::new(1, 2)); 268 test_archive(&U16Vec3::new(1, 2, 3)); 269 test_archive(&U16Vec4::new(1, 2, 3, 4)); 270 271 use crate::{UVec2, UVec3, UVec4}; 272 test_archive(&UVec2::new(1, 2)); 273 test_archive(&UVec3::new(1, 2, 3)); 274 test_archive(&UVec4::new(1, 2, 3, 4)); 275 276 use crate::{U64Vec2, U64Vec3, U64Vec4}; 277 test_archive(&U64Vec2::new(1, 2)); 278 test_archive(&U64Vec3::new(1, 2, 3)); 279 test_archive(&U64Vec4::new(1, 2, 3, 4)); 280 } 281 } 282