From 583fde05fe8233cedb2e83280a66d453b73295f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20L=C3=B6schner?= Date: Tue, 28 Dec 2021 12:36:52 +0100 Subject: [PATCH] Add comment explaining intermediate types for serialization --- nalgebra-sparse/src/coo.rs | 15 +++++++++++++++ nalgebra-sparse/src/csc.rs | 15 +++++++++++++++ nalgebra-sparse/src/csr.rs | 15 +++++++++++++++ nalgebra-sparse/src/pattern.rs | 15 +++++++++++++++ 4 files changed, 60 insertions(+) diff --git a/nalgebra-sparse/src/coo.rs b/nalgebra-sparse/src/coo.rs index 4ad382dc..91ba207d 100644 --- a/nalgebra-sparse/src/coo.rs +++ b/nalgebra-sparse/src/coo.rs @@ -279,6 +279,21 @@ mod serde_serialize { use super::CooMatrix; use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; + /// This is an intermediate type for (de)serializing `CooMatrix`. + /// + /// Deserialization requires using a `try_from_*` function for validation. We could have used + /// the `remote = "Self"` trick (https://github.com/serde-rs/serde/issues/1220) which allows + /// to directly serialize/deserialize the original fields and combine it with validation. + /// However, this would lead to nested serialization of the `CsMatrix` and `SparsityPattern` + /// types. Instead, we decided that we want a more human-readable serialization format using + /// field names like `row_indices` and `col_indices`. The easiest way to achieve this is to + /// introduce an intermediate type. It also allows the serialization format to stay constant + /// even if the internal layout in `nalgebra` changes. + /// + /// We want to avoid unnecessary copies when serializing (i.e. cloning slices into owned + /// storage). Therefore, we use generic arguments to allow using slices during serialization and + /// owned storage (i.e. `Vec`) during deserialization. Without a major update of serde, slices + /// and `Vec`s should always (de)serialize identically. #[derive(Serialize, Deserialize)] struct CooMatrixSerializationData { nrows: usize, diff --git a/nalgebra-sparse/src/csc.rs b/nalgebra-sparse/src/csc.rs index c3c843c7..7c9bb74a 100644 --- a/nalgebra-sparse/src/csc.rs +++ b/nalgebra-sparse/src/csc.rs @@ -525,6 +525,21 @@ mod serde_serialize { use super::CscMatrix; use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; + /// This is an intermediate type for (de)serializing `CscMatrix`. + /// + /// Deserialization requires using a `try_from_*` function for validation. We could have used + /// the `remote = "Self"` trick (https://github.com/serde-rs/serde/issues/1220) which allows + /// to directly serialize/deserialize the original fields and combine it with validation. + /// However, this would lead to nested serialization of the `CsMatrix` and `SparsityPattern` + /// types. Instead, we decided that we want a more human-readable serialization format using + /// field names like `col_offsets` and `row_indices`. The easiest way to achieve this is to + /// introduce an intermediate type. It also allows the serialization format to stay constant + /// even if the internal layout in `nalgebra` changes. + /// + /// We want to avoid unnecessary copies when serializing (i.e. cloning slices into owned + /// storage). Therefore, we use generic arguments to allow using slices during serialization and + /// owned storage (i.e. `Vec`) during deserialization. Without a major update of serde, slices + /// and `Vec`s should always (de)serialize identically. #[derive(Serialize, Deserialize)] struct CscMatrixSerializationData { nrows: usize, diff --git a/nalgebra-sparse/src/csr.rs b/nalgebra-sparse/src/csr.rs index 88c335b2..eb35b335 100644 --- a/nalgebra-sparse/src/csr.rs +++ b/nalgebra-sparse/src/csr.rs @@ -596,6 +596,21 @@ mod serde_serialize { use super::CsrMatrix; use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; + /// This is an intermediate type for (de)serializing `CsrMatrix`. + /// + /// Deserialization requires using a `try_from_*` function for validation. We could have used + /// the `remote = "Self"` trick (https://github.com/serde-rs/serde/issues/1220) which allows + /// to directly serialize/deserialize the original fields and combine it with validation. + /// However, this would lead to nested serialization of the `CsMatrix` and `SparsityPattern` + /// types. Instead, we decided that we want a more human-readable serialization format using + /// field names like `row_offsets` and `cal_indices`. The easiest way to achieve this is to + /// introduce an intermediate type. It also allows the serialization format to stay constant + /// even if the internal layout in `nalgebra` changes. + /// + /// We want to avoid unnecessary copies when serializing (i.e. cloning slices into owned + /// storage). Therefore, we use generic arguments to allow using slices during serialization and + /// owned storage (i.e. `Vec`) during deserialization. Without a major update of serde, slices + /// and `Vec`s should always (de)serialize identically. #[derive(Serialize, Deserialize)] struct CsrMatrixSerializationData { nrows: usize, diff --git a/nalgebra-sparse/src/pattern.rs b/nalgebra-sparse/src/pattern.rs index 82a93ffd..2bc9e939 100644 --- a/nalgebra-sparse/src/pattern.rs +++ b/nalgebra-sparse/src/pattern.rs @@ -294,6 +294,21 @@ mod serde_serialize { use super::SparsityPattern; use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; + /// This is an intermediate type for (de)serializing `SparsityPattern`. + /// + /// Deserialization requires using a `try_from_*` function for validation. We could have used + /// the `remote = "Self"` trick (https://github.com/serde-rs/serde/issues/1220) which allows + /// to directly serialize/deserialize the original fields and combine it with validation. + /// However, this would lead to nested serialization of the `CsMatrix` and `SparsityPattern` + /// types. Instead, we decided that we want a more human-readable serialization format using + /// field names like `major_offsets` and `minor_indices`. The easiest way to achieve this is to + /// introduce an intermediate type. It also allows the serialization format to stay constant + /// even when the internal layout in `nalgebra` changes. + /// + /// We want to avoid unnecessary copies when serializing (i.e. cloning slices into owned + /// storage). Therefore, we use generic arguments to allow using slices during serialization and + /// owned storage (i.e. `Vec`) during deserialization. Without a major update of serde, slices + /// and `Vec`s should always (de)serialize identically. #[derive(Serialize, Deserialize)] struct SparsityPatternSerializationData { major_dim: usize,