From a8fa7f71c0cb918b3dc0cd4d0ff0881fc2248c34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20L=C3=B6schner?= Date: Thu, 9 Dec 2021 18:18:32 +0100 Subject: [PATCH] Unify separate (de)serialization helper structs by using Cow<'a, [T]> --- nalgebra-sparse/src/coo.rs | 40 +++++++++++++--------------------- nalgebra-sparse/src/csc.rs | 40 +++++++++++++--------------------- nalgebra-sparse/src/csr.rs | 40 +++++++++++++--------------------- nalgebra-sparse/src/pattern.rs | 27 ++++++++--------------- 4 files changed, 54 insertions(+), 93 deletions(-) diff --git a/nalgebra-sparse/src/coo.rs b/nalgebra-sparse/src/coo.rs index 15b23566..d3612bdc 100644 --- a/nalgebra-sparse/src/coo.rs +++ b/nalgebra-sparse/src/coo.rs @@ -1,6 +1,7 @@ //! An implementation of the COO sparse matrix format. use crate::SparseFormatError; +use std::borrow::Cow; #[cfg(feature = "serde-serialize")] use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; @@ -278,19 +279,19 @@ impl CooMatrix { } #[cfg(feature = "serde-serialize")] -#[derive(Serialize)] -struct CooMatrixSerializationData<'a, T> { +#[derive(Serialize, Deserialize)] +struct CooMatrixSerializationData<'a, T: Clone> { nrows: usize, ncols: usize, - row_indices: &'a [usize], - col_indices: &'a [usize], - values: &'a [T], + row_indices: Cow<'a, [usize]>, + col_indices: Cow<'a, [usize]>, + values: Cow<'a, [T]>, } #[cfg(feature = "serde-serialize")] impl Serialize for CooMatrix where - T: Serialize, + T: Serialize + Clone, { fn serialize(&self, serializer: S) -> Result where @@ -299,42 +300,31 @@ where CooMatrixSerializationData { nrows: self.nrows(), ncols: self.ncols(), - row_indices: self.row_indices(), - col_indices: self.col_indices(), - values: self.values(), + row_indices: self.row_indices().into(), + col_indices: self.col_indices().into(), + values: self.values().into(), } .serialize(serializer) } } -#[cfg(feature = "serde-serialize")] -#[derive(Deserialize)] -struct CooMatrixDeserializationData { - nrows: usize, - ncols: usize, - row_indices: Vec, - col_indices: Vec, - values: Vec, -} - #[cfg(feature = "serde-serialize")] impl<'de, T> Deserialize<'de> for CooMatrix where - T: Deserialize<'de>, + T: Deserialize<'de> + Clone, { fn deserialize(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { - let de = CooMatrixDeserializationData::deserialize(deserializer)?; + let de = CooMatrixSerializationData::deserialize(deserializer)?; CooMatrix::try_from_triplets( de.nrows, de.ncols, - de.row_indices, - de.col_indices, - de.values, + de.row_indices.into(), + de.col_indices.into(), + de.values.into(), ) - .map(|m| m.into()) .map_err(|e| de::Error::custom(e)) } } diff --git a/nalgebra-sparse/src/csc.rs b/nalgebra-sparse/src/csc.rs index 54383b01..28af852d 100644 --- a/nalgebra-sparse/src/csc.rs +++ b/nalgebra-sparse/src/csc.rs @@ -7,6 +7,7 @@ use crate::cs::{CsLane, CsLaneIter, CsLaneIterMut, CsLaneMut, CsMatrix}; use crate::csr::CsrMatrix; use crate::pattern::{SparsityPattern, SparsityPatternFormatError, SparsityPatternIter}; use crate::{SparseEntry, SparseEntryMut, SparseFormatError, SparseFormatErrorKind}; +use std::borrow::Cow; use nalgebra::Scalar; use num_traits::One; @@ -523,19 +524,19 @@ impl CscMatrix { } #[cfg(feature = "serde-serialize")] -#[derive(Serialize)] -struct CscMatrixSerializationData<'a, T> { +#[derive(Serialize, Deserialize)] +struct CscMatrixSerializationData<'a, T: Clone> { nrows: usize, ncols: usize, - col_offsets: &'a [usize], - row_indices: &'a [usize], - values: &'a [T], + col_offsets: Cow<'a, [usize]>, + row_indices: Cow<'a, [usize]>, + values: Cow<'a, [T]>, } #[cfg(feature = "serde-serialize")] impl Serialize for CscMatrix where - T: Serialize, + T: Serialize + Clone, { fn serialize(&self, serializer: S) -> Result where @@ -544,42 +545,31 @@ where CscMatrixSerializationData { nrows: self.nrows(), ncols: self.ncols(), - col_offsets: self.col_offsets(), - row_indices: self.row_indices(), - values: self.values(), + col_offsets: Cow::Borrowed(self.col_offsets()), + row_indices: Cow::Borrowed(self.row_indices()), + values: Cow::Borrowed(self.values()), } .serialize(serializer) } } -#[cfg(feature = "serde-serialize")] -#[derive(Deserialize)] -struct CscMatrixDeserializationData { - nrows: usize, - ncols: usize, - col_offsets: Vec, - row_indices: Vec, - values: Vec, -} - #[cfg(feature = "serde-serialize")] impl<'de, T> Deserialize<'de> for CscMatrix where - T: Deserialize<'de>, + T: Deserialize<'de> + Clone, { fn deserialize(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { - let de = CscMatrixDeserializationData::deserialize(deserializer)?; + let de = CscMatrixSerializationData::deserialize(deserializer)?; CscMatrix::try_from_csc_data( de.nrows, de.ncols, - de.col_offsets, - de.row_indices, - de.values, + de.col_offsets.into(), + de.row_indices.into(), + de.values.into(), ) - .map(|m| m.into()) .map_err(|e| de::Error::custom(e)) } } diff --git a/nalgebra-sparse/src/csr.rs b/nalgebra-sparse/src/csr.rs index 804606ca..43fb2118 100644 --- a/nalgebra-sparse/src/csr.rs +++ b/nalgebra-sparse/src/csr.rs @@ -6,6 +6,7 @@ use crate::cs::{CsLane, CsLaneIter, CsLaneIterMut, CsLaneMut, CsMatrix}; use crate::csc::CscMatrix; use crate::pattern::{SparsityPattern, SparsityPatternFormatError, SparsityPatternIter}; use crate::{SparseEntry, SparseEntryMut, SparseFormatError, SparseFormatErrorKind}; +use std::borrow::Cow; use nalgebra::Scalar; use num_traits::One; @@ -594,19 +595,19 @@ impl CsrMatrix { } #[cfg(feature = "serde-serialize")] -#[derive(Serialize)] -struct CsrMatrixSerializationData<'a, T> { +#[derive(Serialize, Deserialize)] +struct CsrMatrixSerializationData<'a, T: Clone> { nrows: usize, ncols: usize, - row_offsets: &'a [usize], - col_indices: &'a [usize], - values: &'a [T], + row_offsets: Cow<'a, [usize]>, + col_indices: Cow<'a, [usize]>, + values: Cow<'a, [T]>, } #[cfg(feature = "serde-serialize")] impl Serialize for CsrMatrix where - T: Serialize, + T: Serialize + Clone, { fn serialize(&self, serializer: S) -> Result where @@ -615,42 +616,31 @@ where CsrMatrixSerializationData { nrows: self.nrows(), ncols: self.ncols(), - row_offsets: self.row_offsets(), - col_indices: self.col_indices(), - values: self.values(), + row_offsets: Cow::Borrowed(self.row_offsets()), + col_indices: Cow::Borrowed(self.col_indices()), + values: Cow::Borrowed(self.values()), } .serialize(serializer) } } -#[cfg(feature = "serde-serialize")] -#[derive(Deserialize)] -struct CsrMatrixDeserializationData { - nrows: usize, - ncols: usize, - row_offsets: Vec, - col_indices: Vec, - values: Vec, -} - #[cfg(feature = "serde-serialize")] impl<'de, T> Deserialize<'de> for CsrMatrix where - T: Deserialize<'de>, + T: Deserialize<'de> + Clone, { fn deserialize(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { - let de = CsrMatrixDeserializationData::deserialize(deserializer)?; + let de = CsrMatrixSerializationData::deserialize(deserializer)?; CsrMatrix::try_from_csr_data( de.nrows, de.ncols, - de.row_offsets, - de.col_indices, - de.values, + de.row_offsets.into(), + de.col_indices.into(), + de.values.into(), ) - .map(|m| m.into()) .map_err(|e| de::Error::custom(e)) } } diff --git a/nalgebra-sparse/src/pattern.rs b/nalgebra-sparse/src/pattern.rs index 818cf748..5f01ea10 100644 --- a/nalgebra-sparse/src/pattern.rs +++ b/nalgebra-sparse/src/pattern.rs @@ -1,6 +1,7 @@ //! Sparsity patterns for CSR and CSC matrices. use crate::cs::transpose_cs; use crate::SparseFormatError; +use std::borrow::Cow; use std::error::Error; use std::fmt; @@ -293,12 +294,12 @@ pub enum SparsityPatternFormatError { } #[cfg(feature = "serde-serialize")] -#[derive(Serialize)] +#[derive(Serialize, Deserialize)] struct SparsityPatternSerializationData<'a> { major_dim: usize, minor_dim: usize, - major_offsets: &'a [usize], - minor_indices: &'a [usize], + major_offsets: Cow<'a, [usize]>, + minor_indices: Cow<'a, [usize]>, } #[cfg(feature = "serde-serialize")] @@ -310,36 +311,26 @@ impl Serialize for SparsityPattern { SparsityPatternSerializationData { major_dim: self.major_dim(), minor_dim: self.minor_dim(), - major_offsets: self.major_offsets(), - minor_indices: self.minor_indices(), + major_offsets: Cow::Borrowed(self.major_offsets()), + minor_indices: Cow::Borrowed(self.minor_indices()), } .serialize(serializer) } } -#[cfg(feature = "serde-serialize")] -#[derive(Deserialize)] -struct SparsityPatternDeserializationData { - major_dim: usize, - minor_dim: usize, - major_offsets: Vec, - minor_indices: Vec, -} - #[cfg(feature = "serde-serialize")] impl<'de> Deserialize<'de> for SparsityPattern { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { - let de = SparsityPatternDeserializationData::deserialize(deserializer)?; + let de = SparsityPatternSerializationData::deserialize(deserializer)?; SparsityPattern::try_from_offsets_and_indices( de.major_dim, de.minor_dim, - de.major_offsets, - de.minor_indices, + de.major_offsets.into(), + de.minor_indices.into(), ) - .map(|m| m.into()) .map_err(|e| de::Error::custom(e)) } }