Merge pull request #251 from Ralith/unnested-serialization
Remove gratuitous indirection in serialization impls
This commit is contained in:
commit
7a62b68c38
|
@ -7,9 +7,11 @@ use std::any::Any;
|
||||||
use std::ops::{Add, Sub, Mul, Div};
|
use std::ops::{Add, Sub, Mul, Div};
|
||||||
use typenum::{self, Unsigned, UInt, B1, Bit, UTerm, Sum, Prod, Diff, Quot};
|
use typenum::{self, Unsigned, UInt, B1, Bit, UTerm, Sum, Prod, Diff, Quot};
|
||||||
|
|
||||||
|
#[cfg(feature = "serde-serialize")]
|
||||||
|
use serde::{Serialize, Serializer, Deserialize, Deserializer};
|
||||||
|
|
||||||
/// Dim of dynamically-sized algebraic entities.
|
/// Dim of dynamically-sized algebraic entities.
|
||||||
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
|
#[derive(Clone, Copy, Eq, PartialEq, Debug)]
|
||||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
|
||||||
pub struct Dynamic {
|
pub struct Dynamic {
|
||||||
value: usize
|
value: usize
|
||||||
}
|
}
|
||||||
|
@ -24,6 +26,24 @@ impl Dynamic {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "serde-serialize")]
|
||||||
|
impl Serialize for Dynamic {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where S: Serializer
|
||||||
|
{
|
||||||
|
self.value.serialize(serializer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "serde-serialize")]
|
||||||
|
impl<'de> Deserialize<'de> for Dynamic {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where D: Deserializer<'de>
|
||||||
|
{
|
||||||
|
usize::deserialize(deserializer).map(|x| Dynamic { value: x })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Trait implemented by `Dynamic`.
|
/// Trait implemented by `Dynamic`.
|
||||||
pub trait IsDynamic { }
|
pub trait IsDynamic { }
|
||||||
/// Trait implemented by `Dynamic` and type-level integers different from `U1`.
|
/// Trait implemented by `Dynamic` and type-level integers different from `U1`.
|
||||||
|
|
|
@ -7,6 +7,9 @@ use std::any::TypeId;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use approx::ApproxEq;
|
use approx::ApproxEq;
|
||||||
|
|
||||||
|
#[cfg(feature = "serde-serialize")]
|
||||||
|
use serde::{Serialize, Serializer, Deserialize, Deserializer};
|
||||||
|
|
||||||
use alga::general::{Ring, Real};
|
use alga::general::{Ring, Real};
|
||||||
|
|
||||||
use core::{Scalar, Unit};
|
use core::{Scalar, Unit};
|
||||||
|
@ -83,16 +86,42 @@ Matrix<NNew, R, C, <<S as Storage<NOld, R, C>>::Alloc as Allocator<NNew, R, C>>:
|
||||||
/// some concrete types for `N` and a compatible data storage type `S`).
|
/// some concrete types for `N` and a compatible data storage type `S`).
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Hash, Debug, Clone, Copy)]
|
#[derive(Hash, Debug, Clone, Copy)]
|
||||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
|
||||||
pub struct Matrix<N: Scalar, R: Dim, C: Dim, S> {
|
pub struct Matrix<N: Scalar, R: Dim, C: Dim, S> {
|
||||||
/// The data storage that contains all the matrix components and informations about its number
|
/// The data storage that contains all the matrix components and informations about its number
|
||||||
/// of rows and column (if needed).
|
/// of rows and column (if needed).
|
||||||
pub data: S,
|
pub data: S,
|
||||||
|
|
||||||
#[cfg_attr(feature = "serde-serialize", serde(skip_serializing, skip_deserializing))]
|
|
||||||
_phantoms: PhantomData<(N, R, C)>
|
_phantoms: PhantomData<(N, R, C)>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "serde-serialize")]
|
||||||
|
impl<N, R, C, S> Serialize for Matrix<N, R, C, S>
|
||||||
|
where N: Scalar,
|
||||||
|
R: Dim,
|
||||||
|
C: Dim,
|
||||||
|
S: Serialize,
|
||||||
|
{
|
||||||
|
fn serialize<T>(&self, serializer: T) -> Result<T::Ok, T::Error>
|
||||||
|
where T: Serializer
|
||||||
|
{
|
||||||
|
self.data.serialize(serializer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "serde-serialize")]
|
||||||
|
impl<'de, N, R, C, S> Deserialize<'de> for Matrix<N, R, C, S>
|
||||||
|
where N: Scalar,
|
||||||
|
R: Dim,
|
||||||
|
C: Dim,
|
||||||
|
S: Deserialize<'de>,
|
||||||
|
{
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where D: Deserializer<'de>
|
||||||
|
{
|
||||||
|
S::deserialize(deserializer).map(|x| Matrix { data: x, _phantoms: PhantomData })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<N: Scalar, R: Dim, C: Dim, S> Matrix<N, R, C, S> {
|
impl<N: Scalar, R: Dim, C: Dim, S> Matrix<N, R, C, S> {
|
||||||
/// Creates a new matrix with the given data without statically checking that the matrix
|
/// Creates a new matrix with the given data without statically checking that the matrix
|
||||||
/// dimension matches the storage dimension.
|
/// dimension matches the storage dimension.
|
||||||
|
|
|
@ -2,6 +2,9 @@ use std::mem;
|
||||||
use std::ops::{Neg, Deref};
|
use std::ops::{Neg, Deref};
|
||||||
use approx::ApproxEq;
|
use approx::ApproxEq;
|
||||||
|
|
||||||
|
#[cfg(feature = "serde-serialize")]
|
||||||
|
use serde::{Serialize, Serializer, Deserialize, Deserializer};
|
||||||
|
|
||||||
use alga::general::SubsetOf;
|
use alga::general::SubsetOf;
|
||||||
use alga::linear::NormedSpace;
|
use alga::linear::NormedSpace;
|
||||||
|
|
||||||
|
@ -11,11 +14,28 @@ use alga::linear::NormedSpace;
|
||||||
/// Use `.as_ref()` or `.unwrap()` to obtain the undelying value by-reference or by-move.
|
/// Use `.as_ref()` or `.unwrap()` to obtain the undelying value by-reference or by-move.
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Eq, PartialEq, Clone, Hash, Debug, Copy)]
|
#[derive(Eq, PartialEq, Clone, Hash, Debug, Copy)]
|
||||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
|
||||||
pub struct Unit<T> {
|
pub struct Unit<T> {
|
||||||
value: T
|
value: T
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "serde-serialize")]
|
||||||
|
impl<T: Serialize> Serialize for Unit<T> {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where S: Serializer
|
||||||
|
{
|
||||||
|
self.value.serialize(serializer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "serde-serialize")]
|
||||||
|
impl<'de, T: Deserialize<'de>> Deserialize<'de> for Unit<T> {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where D: Deserializer<'de>
|
||||||
|
{
|
||||||
|
T::deserialize(deserializer).map(|x| Unit { value: x })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T: NormedSpace> Unit<T> {
|
impl<T: NormedSpace> Unit<T> {
|
||||||
/// Normalize the given value and return it wrapped on a `Unit` structure.
|
/// Normalize the given value and return it wrapped on a `Unit` structure.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
use quickcheck::{Arbitrary, Gen};
|
use quickcheck::{Arbitrary, Gen};
|
||||||
use rand::{Rand, Rng};
|
use rand::{Rand, Rng};
|
||||||
|
|
||||||
|
#[cfg(feature = "serde-serialize")]
|
||||||
|
use serde::{Serialize, Serializer, Deserialize, Deserializer};
|
||||||
|
|
||||||
use alga::general::Real;
|
use alga::general::Real;
|
||||||
|
|
||||||
use core::{Scalar, SquareMatrix, OwnedSquareMatrix, ColumnVector, OwnedColumnVector, MatrixArray};
|
use core::{Scalar, SquareMatrix, OwnedSquareMatrix, ColumnVector, OwnedColumnVector, MatrixArray};
|
||||||
|
@ -14,11 +17,36 @@ use geometry::{PointBase, OwnedPoint};
|
||||||
|
|
||||||
/// A 3D orthographic projection stored as an homogeneous 4x4 matrix.
|
/// A 3D orthographic projection stored as an homogeneous 4x4 matrix.
|
||||||
#[derive(Debug, Clone, Copy)] // FIXME: Hash
|
#[derive(Debug, Clone, Copy)] // FIXME: Hash
|
||||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
|
||||||
pub struct OrthographicBase<N: Scalar, S: Storage<N, U4, U4>> {
|
pub struct OrthographicBase<N: Scalar, S: Storage<N, U4, U4>> {
|
||||||
matrix: SquareMatrix<N, U4, S>
|
matrix: SquareMatrix<N, U4, S>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "serde-serialize")]
|
||||||
|
impl<N, S> Serialize for OrthographicBase<N, S>
|
||||||
|
where N: Scalar,
|
||||||
|
S: Storage<N, U4, U4>,
|
||||||
|
SquareMatrix<N, U4, S>: Serialize,
|
||||||
|
{
|
||||||
|
fn serialize<T>(&self, serializer: T) -> Result<T::Ok, T::Error>
|
||||||
|
where T: Serializer
|
||||||
|
{
|
||||||
|
self.matrix.serialize(serializer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "serde-serialize")]
|
||||||
|
impl<'de, N, S> Deserialize<'de> for OrthographicBase<N, S>
|
||||||
|
where N: Scalar,
|
||||||
|
S: Storage<N, U4, U4>,
|
||||||
|
SquareMatrix<N, U4, S>: Deserialize<'de>,
|
||||||
|
{
|
||||||
|
fn deserialize<T>(deserializer: T) -> Result<Self, T::Error>
|
||||||
|
where T: Deserializer<'de>
|
||||||
|
{
|
||||||
|
SquareMatrix::deserialize(deserializer).map(|x| OrthographicBase { matrix: x })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A 3D orthographic projection stored as a static homogeneous 4x4 matrix.
|
/// A 3D orthographic projection stored as a static homogeneous 4x4 matrix.
|
||||||
pub type Orthographic3<N> = OrthographicBase<N, MatrixArray<N, U4, U4>>;
|
pub type Orthographic3<N> = OrthographicBase<N, MatrixArray<N, U4, U4>>;
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
use quickcheck::{Arbitrary, Gen};
|
use quickcheck::{Arbitrary, Gen};
|
||||||
use rand::{Rand, Rng};
|
use rand::{Rand, Rng};
|
||||||
|
|
||||||
|
#[cfg(feature = "serde-serialize")]
|
||||||
|
use serde::{Serialize, Serializer, Deserialize, Deserializer};
|
||||||
|
|
||||||
use alga::general::Real;
|
use alga::general::Real;
|
||||||
|
|
||||||
use core::{Scalar, SquareMatrix, OwnedSquareMatrix, ColumnVector, OwnedColumnVector, MatrixArray};
|
use core::{Scalar, SquareMatrix, OwnedSquareMatrix, ColumnVector, OwnedColumnVector, MatrixArray};
|
||||||
|
@ -14,11 +17,36 @@ use geometry::{PointBase, OwnedPoint};
|
||||||
|
|
||||||
/// A 3D perspective projection stored as an homogeneous 4x4 matrix.
|
/// A 3D perspective projection stored as an homogeneous 4x4 matrix.
|
||||||
#[derive(Debug, Clone, Copy)] // FIXME: Hash
|
#[derive(Debug, Clone, Copy)] // FIXME: Hash
|
||||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
|
||||||
pub struct PerspectiveBase<N: Scalar, S: Storage<N, U4, U4>> {
|
pub struct PerspectiveBase<N: Scalar, S: Storage<N, U4, U4>> {
|
||||||
matrix: SquareMatrix<N, U4, S>
|
matrix: SquareMatrix<N, U4, S>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "serde-serialize")]
|
||||||
|
impl<N, S> Serialize for PerspectiveBase<N, S>
|
||||||
|
where N: Scalar,
|
||||||
|
S: Storage<N, U4, U4>,
|
||||||
|
SquareMatrix<N, U4, S>: Serialize,
|
||||||
|
{
|
||||||
|
fn serialize<T>(&self, serializer: T) -> Result<T::Ok, T::Error>
|
||||||
|
where T: Serializer
|
||||||
|
{
|
||||||
|
self.matrix.serialize(serializer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "serde-serialize")]
|
||||||
|
impl<'de, N, S> Deserialize<'de> for PerspectiveBase<N, S>
|
||||||
|
where N: Scalar,
|
||||||
|
S: Storage<N, U4, U4>,
|
||||||
|
SquareMatrix<N, U4, S>: Deserialize<'de>,
|
||||||
|
{
|
||||||
|
fn deserialize<T>(deserializer: T) -> Result<Self, T::Error>
|
||||||
|
where T: Deserializer<'de>
|
||||||
|
{
|
||||||
|
SquareMatrix::deserialize(deserializer).map(|x| PerspectiveBase { matrix: x })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A 3D perspective projection stored as a static homogeneous 4x4 matrix.
|
/// A 3D perspective projection stored as a static homogeneous 4x4 matrix.
|
||||||
pub type Perspective3<N> = PerspectiveBase<N, MatrixArray<N, U4, U4>>;
|
pub type Perspective3<N> = PerspectiveBase<N, MatrixArray<N, U4, U4>>;
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,9 @@ use std::fmt;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use approx::ApproxEq;
|
use approx::ApproxEq;
|
||||||
|
|
||||||
|
#[cfg(feature = "serde-serialize")]
|
||||||
|
use serde::{Serialize, Serializer, Deserialize, Deserializer};
|
||||||
|
|
||||||
use core::{Scalar, ColumnVector, OwnedColumnVector};
|
use core::{Scalar, ColumnVector, OwnedColumnVector};
|
||||||
use core::iter::{MatrixIter, MatrixIterMut};
|
use core::iter::{MatrixIter, MatrixIterMut};
|
||||||
use core::dimension::{DimName, DimNameSum, DimNameAdd, U1};
|
use core::dimension::{DimName, DimNameSum, DimNameAdd, U1};
|
||||||
|
@ -24,7 +27,6 @@ pub type OwnedPoint<N, D, A> = PointBase<N, D, <A as Allocator<N, D, U1>>::Buffe
|
||||||
/// A point in a n-dimensional euclidean space.
|
/// A point in a n-dimensional euclidean space.
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Hash, Debug)]
|
#[derive(Hash, Debug)]
|
||||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
|
||||||
pub struct PointBase<N: Scalar, D: DimName, S: Storage<N, D, U1>> {
|
pub struct PointBase<N: Scalar, D: DimName, S: Storage<N, D, U1>> {
|
||||||
/// The coordinates of this point, i.e., the shift from the origin.
|
/// The coordinates of this point, i.e., the shift from the origin.
|
||||||
pub coords: ColumnVector<N, D, S>
|
pub coords: ColumnVector<N, D, S>
|
||||||
|
@ -45,6 +47,34 @@ impl<N, D, S> Clone for PointBase<N, D, S>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "serde-serialize")]
|
||||||
|
impl<N, D, S> Serialize for PointBase<N, D, S>
|
||||||
|
where N: Scalar,
|
||||||
|
D: DimName,
|
||||||
|
S: Storage<N, D, U1>,
|
||||||
|
ColumnVector<N, D, S>: Serialize,
|
||||||
|
{
|
||||||
|
fn serialize<T>(&self, serializer: T) -> Result<T::Ok, T::Error>
|
||||||
|
where T: Serializer
|
||||||
|
{
|
||||||
|
self.coords.serialize(serializer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "serde-serialize")]
|
||||||
|
impl<'de, N, D, S> Deserialize<'de> for PointBase<N, D, S>
|
||||||
|
where N: Scalar,
|
||||||
|
D: DimName,
|
||||||
|
S: Storage<N, D, U1>,
|
||||||
|
ColumnVector<N, D, S>: Deserialize<'de>,
|
||||||
|
{
|
||||||
|
fn deserialize<T>(deserializer: T) -> Result<Self, T::Error>
|
||||||
|
where T: Deserializer<'de>
|
||||||
|
{
|
||||||
|
ColumnVector::deserialize(deserializer).map(|x| PointBase { coords: x })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<N: Scalar, D: DimName, S: Storage<N, D, U1>> PointBase<N, D, S> {
|
impl<N: Scalar, D: DimName, S: Storage<N, D, U1>> PointBase<N, D, S> {
|
||||||
/// Creates a new point with the given coordinates.
|
/// Creates a new point with the given coordinates.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -2,6 +2,9 @@ use std::fmt;
|
||||||
use num::Zero;
|
use num::Zero;
|
||||||
use approx::ApproxEq;
|
use approx::ApproxEq;
|
||||||
|
|
||||||
|
#[cfg(feature = "serde-serialize")]
|
||||||
|
use serde::{Serialize, Serializer, Deserialize, Deserializer};
|
||||||
|
|
||||||
use alga::general::Real;
|
use alga::general::Real;
|
||||||
|
|
||||||
use core::{Unit, ColumnVector, OwnedColumnVector, MatrixSlice, MatrixSliceMut, SquareMatrix,
|
use core::{Unit, ColumnVector, OwnedColumnVector, MatrixSlice, MatrixSliceMut, SquareMatrix,
|
||||||
|
@ -22,12 +25,38 @@ pub type OwnedUnitQuaternionBase<N, A> = UnitQuaternionBase<N, <A as Allocator<N
|
||||||
/// that may be used as a rotation.
|
/// that may be used as a rotation.
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Hash, Debug, Copy, Clone)]
|
#[derive(Hash, Debug, Copy, Clone)]
|
||||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
|
||||||
pub struct QuaternionBase<N: Real, S: Storage<N, U4, U1>> {
|
pub struct QuaternionBase<N: Real, S: Storage<N, U4, U1>> {
|
||||||
/// This quaternion as a 4D vector of coordinates in the `[ x, y, z, w ]` storage order.
|
/// This quaternion as a 4D vector of coordinates in the `[ x, y, z, w ]` storage order.
|
||||||
pub coords: ColumnVector<N, U4, S>
|
pub coords: ColumnVector<N, U4, S>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "serde-serialize")]
|
||||||
|
impl<N, S> Serialize for QuaternionBase<N, S>
|
||||||
|
where N: Real,
|
||||||
|
S: Storage<N, U4, U1>,
|
||||||
|
ColumnVector<N, U4, S>: Serialize,
|
||||||
|
{
|
||||||
|
fn serialize<T>(&self, serializer: T) -> Result<T::Ok, T::Error>
|
||||||
|
where T: Serializer
|
||||||
|
{
|
||||||
|
self.coords.serialize(serializer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "serde-serialize")]
|
||||||
|
impl<'de, N, S> Deserialize<'de> for QuaternionBase<N, S>
|
||||||
|
where N: Real,
|
||||||
|
S: Storage<N, U4, U1>,
|
||||||
|
ColumnVector<N, U4, S>: Deserialize<'de>,
|
||||||
|
{
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where D: Deserializer<'de>
|
||||||
|
{
|
||||||
|
ColumnVector::deserialize(deserializer).map(|x| QuaternionBase { coords: x })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<N, S> Eq for QuaternionBase<N, S>
|
impl<N, S> Eq for QuaternionBase<N, S>
|
||||||
where N: Real + Eq,
|
where N: Real + Eq,
|
||||||
S: Storage<N, U4, U1> {
|
S: Storage<N, U4, U1> {
|
||||||
|
|
|
@ -2,6 +2,9 @@ use num::{Zero, One};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use approx::ApproxEq;
|
use approx::ApproxEq;
|
||||||
|
|
||||||
|
#[cfg(feature = "serde-serialize")]
|
||||||
|
use serde::{Serialize, Serializer, Deserialize, Deserializer};
|
||||||
|
|
||||||
use alga::general::Real;
|
use alga::general::Real;
|
||||||
|
|
||||||
use core::{SquareMatrix, Scalar, OwnedSquareMatrix};
|
use core::{SquareMatrix, Scalar, OwnedSquareMatrix};
|
||||||
|
@ -16,11 +19,36 @@ pub type OwnedRotation<N, D, A> = RotationBase<N, D, <A as Allocator<N, D, D>>::
|
||||||
/// A rotation matrix.
|
/// A rotation matrix.
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Hash, Debug, Clone, Copy)]
|
#[derive(Hash, Debug, Clone, Copy)]
|
||||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
|
||||||
pub struct RotationBase<N: Scalar, D: DimName, S> {
|
pub struct RotationBase<N: Scalar, D: DimName, S> {
|
||||||
matrix: SquareMatrix<N, D, S>
|
matrix: SquareMatrix<N, D, S>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "serde-serialize")]
|
||||||
|
impl<N, D, S> Serialize for RotationBase<N, D, S>
|
||||||
|
where N: Scalar,
|
||||||
|
D: DimName,
|
||||||
|
SquareMatrix<N, D, S>: Serialize,
|
||||||
|
{
|
||||||
|
fn serialize<T>(&self, serializer: T) -> Result<T::Ok, T::Error>
|
||||||
|
where T: Serializer
|
||||||
|
{
|
||||||
|
self.matrix.serialize(serializer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "serde-serialize")]
|
||||||
|
impl<'de, N, D, S> Deserialize<'de> for RotationBase<N, D, S>
|
||||||
|
where N: Scalar,
|
||||||
|
D: DimName,
|
||||||
|
SquareMatrix<N, D, S>: Deserialize<'de>,
|
||||||
|
{
|
||||||
|
fn deserialize<T>(deserializer: T) -> Result<Self, T::Error>
|
||||||
|
where T: Deserializer<'de>
|
||||||
|
{
|
||||||
|
SquareMatrix::deserialize(deserializer).map(|x| RotationBase { matrix: x })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<N: Scalar, D: DimName, S: Storage<N, D, D>> RotationBase<N, D, S>
|
impl<N: Scalar, D: DimName, S: Storage<N, D, D>> RotationBase<N, D, S>
|
||||||
where N: Scalar,
|
where N: Scalar,
|
||||||
S: Storage<N, D, D> {
|
S: Storage<N, D, D> {
|
||||||
|
|
|
@ -3,6 +3,9 @@ use std::fmt::Debug;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use approx::ApproxEq;
|
use approx::ApproxEq;
|
||||||
|
|
||||||
|
#[cfg(feature = "serde-serialize")]
|
||||||
|
use serde::{Serialize, Serializer, Deserialize, Deserializer};
|
||||||
|
|
||||||
use alga::general::Field;
|
use alga::general::Field;
|
||||||
|
|
||||||
use core::{Scalar, SquareMatrix, OwnedSquareMatrix};
|
use core::{Scalar, SquareMatrix, OwnedSquareMatrix};
|
||||||
|
@ -53,17 +56,14 @@ where T1: TCategory,
|
||||||
|
|
||||||
/// Tag representing the most general (not necessarily inversible) `Transform` type.
|
/// Tag representing the most general (not necessarily inversible) `Transform` type.
|
||||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
|
||||||
pub enum TGeneral { }
|
pub enum TGeneral { }
|
||||||
|
|
||||||
/// Tag representing the most general inversible `Transform` type.
|
/// Tag representing the most general inversible `Transform` type.
|
||||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
|
||||||
pub enum TProjective { }
|
pub enum TProjective { }
|
||||||
|
|
||||||
/// Tag representing an affine `Transform`. Its bottom-row is equal to `(0, 0 ... 0, 1)`.
|
/// Tag representing an affine `Transform`. Its bottom-row is equal to `(0, 0 ... 0, 1)`.
|
||||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
|
||||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
|
||||||
pub enum TAffine { }
|
pub enum TAffine { }
|
||||||
|
|
||||||
impl TCategory for TGeneral {
|
impl TCategory for TGeneral {
|
||||||
|
@ -159,14 +159,40 @@ pub type OwnedTransform<N, D, A, C>
|
||||||
/// 3D transformation.
|
/// 3D transformation.
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Clone, Copy)] // FIXME: Hash
|
#[derive(Debug, Clone, Copy)] // FIXME: Hash
|
||||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
|
||||||
pub struct TransformBase<N: Scalar, D: DimNameAdd<U1>, S, C: TCategory> {
|
pub struct TransformBase<N: Scalar, D: DimNameAdd<U1>, S, C: TCategory> {
|
||||||
matrix: SquareMatrix<N, DimNameSum<D, U1>, S>,
|
matrix: SquareMatrix<N, DimNameSum<D, U1>, S>,
|
||||||
|
|
||||||
#[cfg_attr(feature = "serde-serialize", serde(skip_serializing, skip_deserializing))]
|
|
||||||
_phantom: PhantomData<C>
|
_phantom: PhantomData<C>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "serde-serialize")]
|
||||||
|
impl<N, D, S, C> Serialize for TransformBase<N, D, S, C>
|
||||||
|
where N: Scalar,
|
||||||
|
D: DimNameAdd<U1>,
|
||||||
|
C: TCategory,
|
||||||
|
SquareMatrix<N, DimNameSum<D, U1>, S>: Serialize,
|
||||||
|
{
|
||||||
|
fn serialize<T>(&self, serializer: T) -> Result<T::Ok, T::Error>
|
||||||
|
where T: Serializer
|
||||||
|
{
|
||||||
|
self.matrix.serialize(serializer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "serde-serialize")]
|
||||||
|
impl<'de, N, D, S, C> Deserialize<'de> for TransformBase<N, D, S, C>
|
||||||
|
where N: Scalar,
|
||||||
|
D: DimNameAdd<U1>,
|
||||||
|
C: TCategory,
|
||||||
|
SquareMatrix<N, DimNameSum<D, U1>, S>: Deserialize<'de>,
|
||||||
|
{
|
||||||
|
fn deserialize<T>(deserializer: T) -> Result<Self, T::Error>
|
||||||
|
where T: Deserializer<'de>
|
||||||
|
{
|
||||||
|
SquareMatrix::deserialize(deserializer).map(|x| TransformBase { matrix: x, _phantom: PhantomData })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// XXX: for some reasons, implementing Clone and Copy manually causes an ICE…
|
// XXX: for some reasons, implementing Clone and Copy manually causes an ICE…
|
||||||
|
|
||||||
impl<N, D, S, C: TCategory> Eq for TransformBase<N, D, S, C>
|
impl<N, D, S, C: TCategory> Eq for TransformBase<N, D, S, C>
|
||||||
|
|
|
@ -2,6 +2,9 @@ use num::{Zero, One};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use approx::ApproxEq;
|
use approx::ApproxEq;
|
||||||
|
|
||||||
|
#[cfg(feature = "serde-serialize")]
|
||||||
|
use serde::{Serialize, Serializer, Deserialize, Deserializer};
|
||||||
|
|
||||||
use alga::general::{Real, ClosedNeg};
|
use alga::general::{Real, ClosedNeg};
|
||||||
|
|
||||||
use core::{Scalar, ColumnVector, OwnedSquareMatrix};
|
use core::{Scalar, ColumnVector, OwnedSquareMatrix};
|
||||||
|
@ -15,13 +18,38 @@ pub type OwnedTranslation<N, D, S> = TranslationBase<N, D, Owned<N, D, U1, <S as
|
||||||
/// A translation.
|
/// A translation.
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Hash, Debug, Clone, Copy)]
|
#[derive(Hash, Debug, Clone, Copy)]
|
||||||
#[cfg_attr(feature = "serde-serialize", derive(Serialize, Deserialize))]
|
|
||||||
pub struct TranslationBase<N: Scalar, D: DimName, S/*: Storage<N, D, U1>*/> {
|
pub struct TranslationBase<N: Scalar, D: DimName, S/*: Storage<N, D, U1>*/> {
|
||||||
/// The translation coordinates, i.e., how much is added to a point's coordinates when it is
|
/// The translation coordinates, i.e., how much is added to a point's coordinates when it is
|
||||||
/// translated.
|
/// translated.
|
||||||
pub vector: ColumnVector<N, D, S>
|
pub vector: ColumnVector<N, D, S>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "serde-serialize")]
|
||||||
|
impl<N, D, S> Serialize for TranslationBase<N, D, S>
|
||||||
|
where N: Scalar,
|
||||||
|
D: DimName,
|
||||||
|
ColumnVector<N, D, S>: Serialize,
|
||||||
|
{
|
||||||
|
fn serialize<T>(&self, serializer: T) -> Result<T::Ok, T::Error>
|
||||||
|
where T: Serializer
|
||||||
|
{
|
||||||
|
self.vector.serialize(serializer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "serde-serialize")]
|
||||||
|
impl<'de, N, D, S> Deserialize<'de> for TranslationBase<N, D, S>
|
||||||
|
where N: Scalar,
|
||||||
|
D: DimName,
|
||||||
|
ColumnVector<N, D, S>: Deserialize<'de>,
|
||||||
|
{
|
||||||
|
fn deserialize<T>(deserializer: T) -> Result<Self, T::Error>
|
||||||
|
where T: Deserializer<'de>
|
||||||
|
{
|
||||||
|
ColumnVector::deserialize(deserializer).map(|x| TranslationBase { vector: x })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<N, D: DimName, S> TranslationBase<N, D, S>
|
impl<N, D: DimName, S> TranslationBase<N, D, S>
|
||||||
where N: Scalar,
|
where N: Scalar,
|
||||||
S: Storage<N, D, U1> {
|
S: Storage<N, D, U1> {
|
||||||
|
|
|
@ -13,7 +13,8 @@ use na::{
|
||||||
IsometryMatrix3,
|
IsometryMatrix3,
|
||||||
Similarity3,
|
Similarity3,
|
||||||
SimilarityMatrix3,
|
SimilarityMatrix3,
|
||||||
Quaternion
|
Quaternion,
|
||||||
|
Unit,
|
||||||
};
|
};
|
||||||
|
|
||||||
macro_rules! test_serde(
|
macro_rules! test_serde(
|
||||||
|
@ -45,3 +46,11 @@ test_serde!(
|
||||||
serde_similarity_matrix3, SimilarityMatrix3;
|
serde_similarity_matrix3, SimilarityMatrix3;
|
||||||
serde_quaternion, Quaternion;
|
serde_quaternion, Quaternion;
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn serde_flat() {
|
||||||
|
// The actual storage is hidden behind three layers of wrapper types that shouldn't appear in serialized form.
|
||||||
|
let v = Unit::new_normalize(Quaternion::new(0., 0., 0., 1.));
|
||||||
|
let serialized = serde_json::to_string(&v).unwrap();
|
||||||
|
assert_eq!(serialized, "[0.0,0.0,1.0,0.0]");
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue