diff --git a/Cargo.toml b/Cargo.toml index a629b5544..ffd37598f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,7 +53,7 @@ convert-glam020 = [ "glam020" ] serde-serialize-no-std = [ "serde", "num-complex/serde" ] serde-serialize = [ "serde-serialize-no-std", "serde/std" ] rkyv-serialize-no-std = [ "rkyv" ] -rkyv-serialize = [ "rkyv-serialize-no-std", "rkyv/std" ] +rkyv-serialize = [ "rkyv-serialize-no-std", "rkyv/std", "bytecheck" ] # Randomness ## To use rand in a #[no-std] environment, enable the @@ -79,7 +79,8 @@ alga = { version = "0.9", default-features = false, optional = true } rand_distr = { version = "0.4", default-features = false, optional = true } matrixmultiply = { version = "0.3", optional = true } serde = { version = "1.0", default-features = false, features = [ "derive" ], optional = true } -rkyv = { version = "~0.6.4", default-features = false, features = ["const_generics"], optional = true } +rkyv = { version = "~0.7.1", optional = true } +bytecheck = { version = "~0.6.1", optional = true } mint = { version = "0.5", optional = true } quickcheck = { version = "1", optional = true } pest = { version = "2", optional = true } diff --git a/src/base/array_storage.rs b/src/base/array_storage.rs index b6bd236a0..3bc71e1a3 100644 --- a/src/base/array_storage.rs +++ b/src/base/array_storage.rs @@ -27,6 +27,11 @@ use std::mem; /// A array-based statically sized matrix data storage. #[repr(transparent)] #[derive(Copy, Clone, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] +#[cfg_attr( + feature = "rkyv-serialize-no-std", + derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) +)] #[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))] pub struct ArrayStorage(pub [[T; R]; C]); @@ -273,45 +278,3 @@ unsafe impl by for ArrayStorage { } - -#[cfg(feature = "rkyv-serialize-no-std")] -mod rkyv_impl { - use super::ArrayStorage; - use rkyv::{offset_of, project_struct, Archive, Deserialize, Fallible, Serialize}; - - impl Archive for ArrayStorage { - type Archived = ArrayStorage; - type Resolver = <[[T; R]; C] as Archive>::Resolver; - - fn resolve( - &self, - pos: usize, - resolver: Self::Resolver, - out: &mut core::mem::MaybeUninit, - ) { - self.0.resolve( - pos + offset_of!(Self::Archived, 0), - resolver, - project_struct!(out: Self::Archived => 0), - ); - } - } - - impl, S: Fallible + ?Sized, const R: usize, const C: usize> Serialize - for ArrayStorage - { - fn serialize(&self, serializer: &mut S) -> Result { - self.0.serialize(serializer) - } - } - - impl - Deserialize, D> for ArrayStorage - where - T::Archived: Deserialize, - { - fn deserialize(&self, deserializer: &mut D) -> Result, D::Error> { - Ok(ArrayStorage(self.0.deserialize(deserializer)?)) - } - } -} diff --git a/src/base/dimension.rs b/src/base/dimension.rs index de51339fe..4be975860 100644 --- a/src/base/dimension.rs +++ b/src/base/dimension.rs @@ -13,6 +13,11 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer}; /// Dim of dynamically-sized algebraic entities. #[derive(Clone, Copy, Eq, PartialEq, Debug)] +#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] +#[cfg_attr( + feature = "rkyv-serialize-no-std", + derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) +)] #[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))] pub struct Dynamic { value: usize, @@ -198,6 +203,11 @@ dim_ops!( ); #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +#[cfg_attr( + feature = "rkyv-serialize-no-std", + derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) +)] +#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] #[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))] pub struct Const; @@ -233,37 +243,6 @@ impl<'de, const D: usize> Deserialize<'de> for Const { } } -#[cfg(feature = "rkyv-serialize-no-std")] -mod rkyv_impl { - use super::Const; - use rkyv::{Archive, Deserialize, Fallible, Serialize}; - - impl Archive for Const { - type Archived = Self; - type Resolver = (); - - fn resolve( - &self, - _: usize, - _: Self::Resolver, - _: &mut core::mem::MaybeUninit, - ) { - } - } - - impl Serialize for Const { - fn serialize(&self, _: &mut S) -> Result { - Ok(()) - } - } - - impl Deserialize for Const { - fn deserialize(&self, _: &mut D) -> Result { - Ok(Const) - } - } -} - pub trait ToConst { type Const: DimName; } diff --git a/src/base/matrix.rs b/src/base/matrix.rs index f12cb3fa6..8f8786c13 100644 --- a/src/base/matrix.rs +++ b/src/base/matrix.rs @@ -150,6 +150,11 @@ pub type MatrixCross = /// some concrete types for `T` and a compatible data storage type `S`). #[repr(C)] #[derive(Clone, Copy)] +#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] +#[cfg_attr( + feature = "rkyv-serialize-no-std", + derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) +)] #[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))] pub struct Matrix { /// The data storage that contains all the matrix components. Disappointed? @@ -288,53 +293,6 @@ where { } -#[cfg(feature = "rkyv-serialize-no-std")] -mod rkyv_impl { - use super::Matrix; - use core::marker::PhantomData; - use rkyv::{offset_of, project_struct, Archive, Deserialize, Fallible, Serialize}; - - impl Archive for Matrix { - type Archived = Matrix; - type Resolver = S::Resolver; - - fn resolve( - &self, - pos: usize, - resolver: Self::Resolver, - out: &mut core::mem::MaybeUninit, - ) { - self.data.resolve( - pos + offset_of!(Self::Archived, data), - resolver, - project_struct!(out: Self::Archived => data), - ); - } - } - - impl, _S: Fallible + ?Sized> Serialize<_S> - for Matrix - { - fn serialize(&self, serializer: &mut _S) -> Result { - self.data.serialize(serializer) - } - } - - impl - Deserialize, D> - for Matrix - where - S::Archived: Deserialize, - { - fn deserialize(&self, deserializer: &mut D) -> Result, D::Error> { - Ok(Matrix { - data: self.data.deserialize(deserializer)?, - _phantoms: PhantomData, - }) - } - } -} - impl Matrix { /// Creates a new matrix with the given data without statically checking that the matrix /// dimension matches the storage dimension. diff --git a/src/base/unit.rs b/src/base/unit.rs index bb8b56a17..6fc000928 100644 --- a/src/base/unit.rs +++ b/src/base/unit.rs @@ -21,6 +21,11 @@ use crate::{Dim, Matrix, OMatrix, RealField, Scalar, SimdComplexField, SimdRealF /// in their documentation, read their dedicated pages directly. #[repr(transparent)] #[derive(Clone, Hash, Copy)] +#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] +#[cfg_attr( + feature = "rkyv-serialize-no-std", + derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) +)] // #[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))] pub struct Unit { pub(crate) value: T, @@ -58,47 +63,6 @@ impl<'de, T: Deserialize<'de>> Deserialize<'de> for Unit { } } -#[cfg(feature = "rkyv-serialize-no-std")] -mod rkyv_impl { - use super::Unit; - use rkyv::{offset_of, project_struct, Archive, Deserialize, Fallible, Serialize}; - - impl Archive for Unit { - type Archived = Unit; - type Resolver = T::Resolver; - - fn resolve( - &self, - pos: usize, - resolver: Self::Resolver, - out: &mut ::core::mem::MaybeUninit, - ) { - self.value.resolve( - pos + offset_of!(Self::Archived, value), - resolver, - project_struct!(out: Self::Archived => value), - ); - } - } - - impl, S: Fallible + ?Sized> Serialize for Unit { - fn serialize(&self, serializer: &mut S) -> Result { - self.value.serialize(serializer) - } - } - - impl Deserialize, D> for Unit - where - T::Archived: Deserialize, - { - fn deserialize(&self, deserializer: &mut D) -> Result, D::Error> { - Ok(Unit { - value: self.value.deserialize(deserializer)?, - }) - } - } -} - #[cfg(feature = "cuda")] unsafe impl cust_core::DeviceCopy for Unit> where diff --git a/src/geometry/dual_quaternion.rs b/src/geometry/dual_quaternion.rs index 719ae13d8..6f1b70536 100644 --- a/src/geometry/dual_quaternion.rs +++ b/src/geometry/dual_quaternion.rs @@ -40,6 +40,11 @@ use simba::scalar::{ClosedNeg, RealField}; /// See #[repr(C)] #[derive(Debug, Copy, Clone)] +#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] +#[cfg_attr( + feature = "rkyv-serialize-no-std", + derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) +)] #[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))] pub struct DualQuaternion { /// The real component of the quaternion diff --git a/src/geometry/isometry.rs b/src/geometry/isometry.rs index 0179f1fff..921697427 100755 --- a/src/geometry/isometry.rs +++ b/src/geometry/isometry.rs @@ -66,6 +66,11 @@ use crate::geometry::{AbstractRotation, Point, Translation}; Owned>: Deserialize<'de>, T: Scalar")) )] +#[cfg_attr( + feature = "rkyv-serialize-no-std", + derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) +)] +#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] pub struct Isometry { /// The pure rotational part of this isometry. pub rotation: R, @@ -73,66 +78,6 @@ pub struct Isometry { pub translation: Translation, } -#[cfg(feature = "rkyv-serialize-no-std")] -mod rkyv_impl { - use super::Isometry; - use crate::{base::Scalar, geometry::Translation}; - use rkyv::{offset_of, project_struct, Archive, Deserialize, Fallible, Serialize}; - - impl Archive for Isometry - where - T::Archived: Scalar, - { - type Archived = Isometry; - type Resolver = (R::Resolver, as Archive>::Resolver); - - fn resolve( - &self, - pos: usize, - resolver: Self::Resolver, - out: &mut core::mem::MaybeUninit, - ) { - self.rotation.resolve( - pos + offset_of!(Self::Archived, rotation), - resolver.0, - project_struct!(out: Self::Archived => rotation), - ); - self.translation.resolve( - pos + offset_of!(Self::Archived, translation), - resolver.1, - project_struct!(out: Self::Archived => translation), - ); - } - } - - impl, R: Serialize, S: Fallible + ?Sized, const D: usize> - Serialize for Isometry - where - T::Archived: Scalar, - { - fn serialize(&self, serializer: &mut S) -> Result { - Ok(( - self.rotation.serialize(serializer)?, - self.translation.serialize(serializer)?, - )) - } - } - - impl - Deserialize, _D> for Isometry - where - T::Archived: Scalar + Deserialize, - R::Archived: Scalar + Deserialize, - { - fn deserialize(&self, deserializer: &mut _D) -> Result, _D::Error> { - Ok(Isometry { - rotation: self.rotation.deserialize(deserializer)?, - translation: self.translation.deserialize(deserializer)?, - }) - } - } -} - impl hash::Hash for Isometry where Owned>: hash::Hash, diff --git a/src/geometry/orthographic.rs b/src/geometry/orthographic.rs index 1119d4e30..7348f676c 100644 --- a/src/geometry/orthographic.rs +++ b/src/geometry/orthographic.rs @@ -19,6 +19,11 @@ use crate::geometry::{Point3, Projective3}; /// A 3D orthographic projection stored as a homogeneous 4x4 matrix. #[repr(C)] +#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] +#[cfg_attr( + feature = "rkyv-serialize-no-std", + derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) +)] #[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))] #[derive(Copy, Clone)] pub struct Orthographic3 { diff --git a/src/geometry/perspective.rs b/src/geometry/perspective.rs index 8ebab3e4a..351960bbd 100644 --- a/src/geometry/perspective.rs +++ b/src/geometry/perspective.rs @@ -20,6 +20,11 @@ use crate::geometry::{Point3, Projective3}; /// A 3D perspective projection stored as a homogeneous 4x4 matrix. #[repr(C)] +#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] +#[cfg_attr( + feature = "rkyv-serialize-no-std", + derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) +)] #[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))] #[derive(Copy, Clone)] pub struct Perspective3 { diff --git a/src/geometry/point.rs b/src/geometry/point.rs index cdc590faf..306c18e5e 100644 --- a/src/geometry/point.rs +++ b/src/geometry/point.rs @@ -36,6 +36,11 @@ use std::mem::MaybeUninit; /// of said transformations for details. #[repr(C)] #[derive(Clone)] +#[cfg_attr( + feature = "rkyv-serialize-no-std", + derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) +)] +#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] pub struct OPoint where DefaultAllocator: Allocator, diff --git a/src/geometry/quaternion.rs b/src/geometry/quaternion.rs index 987c97574..f38dca6f7 100755 --- a/src/geometry/quaternion.rs +++ b/src/geometry/quaternion.rs @@ -23,6 +23,11 @@ use crate::geometry::{Point3, Rotation}; /// that may be used as a rotation. #[repr(C)] #[derive(Copy, Clone)] +#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] +#[cfg_attr( + feature = "rkyv-serialize-no-std", + derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) +)] #[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))] pub struct Quaternion { /// This quaternion as a 4D vector of coordinates in the `[ x, y, z, w ]` storage order. @@ -97,48 +102,6 @@ where } } -#[cfg(feature = "rkyv-serialize-no-std")] -mod rkyv_impl { - use super::Quaternion; - use crate::base::Vector4; - use rkyv::{offset_of, project_struct, Archive, Deserialize, Fallible, Serialize}; - - impl Archive for Quaternion { - type Archived = Quaternion; - type Resolver = as Archive>::Resolver; - - fn resolve( - &self, - pos: usize, - resolver: Self::Resolver, - out: &mut core::mem::MaybeUninit, - ) { - self.coords.resolve( - pos + offset_of!(Self::Archived, coords), - resolver, - project_struct!(out: Self::Archived => coords), - ); - } - } - - impl, S: Fallible + ?Sized> Serialize for Quaternion { - fn serialize(&self, serializer: &mut S) -> Result { - self.coords.serialize(serializer) - } - } - - impl Deserialize, D> for Quaternion - where - T::Archived: Deserialize, - { - fn deserialize(&self, deserializer: &mut D) -> Result, D::Error> { - Ok(Quaternion { - coords: self.coords.deserialize(deserializer)?, - }) - } - } -} - impl Quaternion where T::Element: SimdRealField, diff --git a/src/geometry/rotation.rs b/src/geometry/rotation.rs index 4dbcfb436..2a8bf4277 100755 --- a/src/geometry/rotation.rs +++ b/src/geometry/rotation.rs @@ -49,6 +49,11 @@ use crate::geometry::Point; /// * [Conversion to a matrix `matrix`, `to_homogeneous`…](#conversion-to-a-matrix) /// #[repr(C)] +#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] +#[cfg_attr( + feature = "rkyv-serialize-no-std", + derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) +)] #[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))] #[derive(Copy, Clone)] pub struct Rotation { diff --git a/src/geometry/scale.rs b/src/geometry/scale.rs index abaeeccc5..37da1ef04 100755 --- a/src/geometry/scale.rs +++ b/src/geometry/scale.rs @@ -17,6 +17,11 @@ use crate::geometry::Point; /// A scale which supports non-uniform scaling. #[repr(C)] +#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] +#[cfg_attr( + feature = "rkyv-serialize-no-std", + derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) +)] #[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))] #[derive(Copy, Clone)] pub struct Scale { @@ -84,49 +89,6 @@ where } } -#[cfg(feature = "rkyv-serialize-no-std")] -mod rkyv_impl { - use super::Scale; - use crate::base::SVector; - use rkyv::{offset_of, project_struct, Archive, Deserialize, Fallible, Serialize}; - - impl Archive for Scale { - type Archived = Scale; - type Resolver = as Archive>::Resolver; - - fn resolve( - &self, - pos: usize, - resolver: Self::Resolver, - out: &mut core::mem::MaybeUninit, - ) { - self.vector.resolve( - pos + offset_of!(Self::Archived, vector), - resolver, - project_struct!(out: Self::Archived => vector), - ); - } - } - - impl, S: Fallible + ?Sized, const D: usize> Serialize for Scale { - fn serialize(&self, serializer: &mut S) -> Result { - self.vector.serialize(serializer) - } - } - - impl Deserialize, _D> - for Scale - where - T::Archived: Deserialize, - { - fn deserialize(&self, deserializer: &mut _D) -> Result, _D::Error> { - Ok(Scale { - vector: self.vector.deserialize(deserializer)?, - }) - } - } -} - impl Scale { /// Inverts `self`. /// diff --git a/src/geometry/similarity.rs b/src/geometry/similarity.rs index 9658685ef..8c38ff1e6 100755 --- a/src/geometry/similarity.rs +++ b/src/geometry/similarity.rs @@ -34,6 +34,11 @@ use crate::geometry::{AbstractRotation, Isometry, Point, Translation}; DefaultAllocator: Allocator>, Owned>: Deserialize<'de>")) )] +#[cfg_attr( + feature = "rkyv-serialize-no-std", + derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) +)] +#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] pub struct Similarity { /// The part of this similarity that does not include the scaling factor. pub isometry: Isometry, diff --git a/src/geometry/translation.rs b/src/geometry/translation.rs index e1921d0a3..bef66f686 100755 --- a/src/geometry/translation.rs +++ b/src/geometry/translation.rs @@ -17,6 +17,11 @@ use crate::geometry::Point; /// A translation. #[repr(C)] +#[cfg_attr(feature = "rkyv-serialize", derive(bytecheck::CheckBytes))] +#[cfg_attr( + feature = "rkyv-serialize-no-std", + derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) +)] #[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))] #[derive(Copy, Clone)] pub struct Translation { @@ -84,49 +89,6 @@ where } } -#[cfg(feature = "rkyv-serialize-no-std")] -mod rkyv_impl { - use super::Translation; - use crate::base::SVector; - use rkyv::{offset_of, project_struct, Archive, Deserialize, Fallible, Serialize}; - - impl Archive for Translation { - type Archived = Translation; - type Resolver = as Archive>::Resolver; - - fn resolve( - &self, - pos: usize, - resolver: Self::Resolver, - out: &mut core::mem::MaybeUninit, - ) { - self.vector.resolve( - pos + offset_of!(Self::Archived, vector), - resolver, - project_struct!(out: Self::Archived => vector), - ); - } - } - - impl, S: Fallible + ?Sized, const D: usize> Serialize for Translation { - fn serialize(&self, serializer: &mut S) -> Result { - self.vector.serialize(serializer) - } - } - - impl Deserialize, _D> - for Translation - where - T::Archived: Deserialize, - { - fn deserialize(&self, deserializer: &mut _D) -> Result, _D::Error> { - Ok(Translation { - vector: self.vector.deserialize(deserializer)?, - }) - } - } -} - impl Translation { /// Creates a new translation from the given vector. #[inline] diff --git a/src/lib.rs b/src/lib.rs index 92b28dcbf..1ee1a3ba7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -78,12 +78,13 @@ an optimized set of tools for computer graphics and physics. Those features incl unused_mut, unused_parens, unused_qualifications, - unused_results, rust_2018_idioms, rust_2018_compatibility, future_incompatible, missing_copy_implementations )] +#![cfg_attr(feature = "rkyv-serialize-no-std", warn(unused_results))] // TODO: deny this once bytecheck stops generating warnings. +#![cfg_attr(not(feature = "rkyv-serialize-no-std"), deny(unused_results))] #![doc( html_favicon_url = "https://nalgebra.org/img/favicon.ico", html_root_url = "https://docs.rs/nalgebra/0.25.0"