From 65fa4cf740facdd2df9d4aeb6b66835710051402 Mon Sep 17 00:00:00 2001 From: Eduard Bopp Date: Mon, 14 Aug 2017 12:07:06 +0200 Subject: [PATCH] Implement Abomonation for static matrices --- Cargo.toml | 3 +++ src/core/matrix.rs | 18 ++++++++++++++++++ src/core/matrix_array.rs | 24 ++++++++++++++++++++++++ src/lib.rs | 2 ++ tests/abomonation.rs | 22 ++++++++++++++++++++++ 5 files changed, 69 insertions(+) create mode 100644 tests/abomonation.rs diff --git a/Cargo.toml b/Cargo.toml index e57e3f48..1e7b3b4e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ path = "src/lib.rs" [features] arbitrary = [ "quickcheck" ] serde-serialize = [ "serde", "serde_derive", "num-complex/serde" ] +abomonation-serialize = [ "abomonation", "abomonation_derive" ] [dependencies] typenum = "1.4" @@ -29,6 +30,8 @@ approx = "0.1" alga = "0.5" serde = { version = "1.0", optional = true } serde_derive = { version = "1.0", optional = true } +abomonation = { version = "0.4", optional = true } +abomonation_derive = { version = "0.2", optional = true } # clippy = "*" [dependencies.quickcheck] diff --git a/src/core/matrix.rs b/src/core/matrix.rs index 6deb899f..b56ce61a 100644 --- a/src/core/matrix.rs +++ b/src/core/matrix.rs @@ -10,6 +10,9 @@ use approx::ApproxEq; #[cfg(feature = "serde-serialize")] use serde::{Serialize, Serializer, Deserialize, Deserializer}; +#[cfg(feature = "abomonation-serialize")] +use abomonation::Abomonation; + use alga::general::{Ring, Real}; use core::{Scalar, Unit}; @@ -122,6 +125,21 @@ impl<'de, N, R, C, S> Deserialize<'de> for Matrix } } +#[cfg(feature = "abomonation-serialize")] +impl Abomonation for Matrix { + unsafe fn entomb(&self, writer: &mut Vec) { + self.data.entomb(writer) + } + + unsafe fn embalm(&mut self) { + self.data.embalm() + } + + unsafe fn exhume<'a, 'b>(&'a mut self, bytes: &'b mut [u8]) -> Option<&'b mut [u8]> { + self.data.exhume(bytes) + } +} + 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/core/matrix_array.rs b/src/core/matrix_array.rs index 5acd67d3..c344a3a3 100644 --- a/src/core/matrix_array.rs +++ b/src/core/matrix_array.rs @@ -13,6 +13,9 @@ use std::mem; #[cfg(feature = "serde-serialize")] use std::marker::PhantomData; +#[cfg(feature = "abomonation-serialize")] +use abomonation::Abomonation; + use typenum::Prod; use generic_array::{ArrayLength, GenericArray}; @@ -299,3 +302,24 @@ where N: Scalar + Deserialize<'a>, } } } + +#[cfg(feature = "abomonation-serialize")] +impl Abomonation for MatrixArray + where R: DimName, + C: DimName, + R::Value: Mul, + Prod: ArrayLength, + N: Abomonation +{ + unsafe fn entomb(&self, writer: &mut Vec) { + self.data.as_slice().entomb(writer) + } + + unsafe fn embalm(&mut self) { + self.data.as_slice().embalm() + } + + unsafe fn exhume<'a, 'b>(&'a mut self, bytes: &'b mut [u8]) -> Option<&'b mut [u8]> { + self.data.as_slice().exhume(bytes) + } +} diff --git a/src/lib.rs b/src/lib.rs index 3ab855d7..0231242b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -94,6 +94,8 @@ extern crate serde; #[cfg(feature = "serde")] #[macro_use] extern crate serde_derive; +#[cfg(feature = "abomonation")] +extern crate abomonation; extern crate num_traits as num; extern crate num_complex; extern crate rand; diff --git a/tests/abomonation.rs b/tests/abomonation.rs new file mode 100644 index 00000000..57696cea --- /dev/null +++ b/tests/abomonation.rs @@ -0,0 +1,22 @@ +extern crate rand; +extern crate nalgebra; +extern crate abomonation; + +use rand::random; +use abomonation::{Abomonation, encode, decode}; +use nalgebra::Matrix3x4; + +#[test] +fn abomonate_matrix3x4() { + assert_encode_and_decode(&random::>()); +} + +fn assert_encode_and_decode(data: &T) { + let mut bytes = Vec::new(); + unsafe { encode(data, &mut bytes); } + + if let Some((result, rest)) = unsafe { decode::(&mut bytes) } { + assert!(result == data); + assert!(rest.len() == 0, "binary data was not decoded completely"); + } +}