use hdf5_pure::mat as mat_pure;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[non_exhaustive]
pub enum Compression {
None,
Deflate {
level: u8,
shuffle: bool,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[non_exhaustive]
pub enum InvalidNamePolicy {
Error,
Sanitize,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[non_exhaustive]
pub enum NullPolicy {
EmptyStructArray,
Omit,
Error,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[non_exhaustive]
pub enum UnsupportedPolicy {
Error,
StringFallback,
LossyNumericWidening,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[non_exhaustive]
pub enum OneDimensionalMode {
ColumnVector,
RowVector,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[non_exhaustive]
pub enum RowMajorPolicy {
ReorderToColumnMajor,
Error,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
#[non_exhaustive]
pub enum LibVer {
Earliest,
V18,
V110,
V112,
V114,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(default)]
pub struct MatV73Options {
pub compression: Compression,
pub invalid_name_policy: InvalidNamePolicy,
pub null_policy: NullPolicy,
pub unsupported_policy: UnsupportedPolicy,
pub one_dimensional_mode: OneDimensionalMode,
pub row_major_policy: RowMajorPolicy,
pub libver: LibVer,
}
impl Default for MatV73Options {
fn default() -> Self {
Self {
compression: Compression::None,
invalid_name_policy: InvalidNamePolicy::Error,
null_policy: NullPolicy::EmptyStructArray,
unsupported_policy: UnsupportedPolicy::Error,
one_dimensional_mode: OneDimensionalMode::ColumnVector,
row_major_policy: RowMajorPolicy::ReorderToColumnMajor,
libver: LibVer::V18,
}
}
}
impl Compression {
fn to_pure(self) -> mat_pure::Compression {
match self {
Compression::None => mat_pure::Compression::None,
Compression::Deflate { level, shuffle } => {
mat_pure::Compression::Deflate { level, shuffle }
}
}
}
}
impl InvalidNamePolicy {
fn to_pure(self) -> mat_pure::InvalidNamePolicy {
match self {
InvalidNamePolicy::Error => mat_pure::InvalidNamePolicy::Error,
InvalidNamePolicy::Sanitize => mat_pure::InvalidNamePolicy::Sanitize,
}
}
}
impl NullPolicy {
fn to_pure(self) -> mat_pure::NullPolicy {
match self {
NullPolicy::EmptyStructArray => mat_pure::NullPolicy::EmptyStructArray,
NullPolicy::Omit => mat_pure::NullPolicy::Omit,
NullPolicy::Error => mat_pure::NullPolicy::Error,
}
}
}
impl UnsupportedPolicy {
fn to_pure(self) -> mat_pure::UnsupportedPolicy {
match self {
UnsupportedPolicy::Error => mat_pure::UnsupportedPolicy::Error,
UnsupportedPolicy::StringFallback => mat_pure::UnsupportedPolicy::StringFallback,
UnsupportedPolicy::LossyNumericWidening => {
mat_pure::UnsupportedPolicy::LossyNumericWidening
}
}
}
}
impl OneDimensionalMode {
fn to_pure(self) -> mat_pure::OneDimensionalMode {
match self {
OneDimensionalMode::ColumnVector => mat_pure::OneDimensionalMode::ColumnVector,
OneDimensionalMode::RowVector => mat_pure::OneDimensionalMode::RowVector,
}
}
}
impl RowMajorPolicy {
fn to_pure(self) -> mat_pure::RowMajorPolicy {
match self {
RowMajorPolicy::ReorderToColumnMajor => mat_pure::RowMajorPolicy::ReorderToColumnMajor,
RowMajorPolicy::Error => mat_pure::RowMajorPolicy::Error,
}
}
}
impl LibVer {
fn to_pure(self) -> hdf5_pure::LibVer {
match self {
LibVer::Earliest => hdf5_pure::LibVer::Earliest,
LibVer::V18 => hdf5_pure::LibVer::V18,
LibVer::V110 => hdf5_pure::LibVer::V110,
LibVer::V112 => hdf5_pure::LibVer::V112,
LibVer::V114 => hdf5_pure::LibVer::V114,
}
}
}
impl MatV73Options {
pub(super) fn to_pure(&self) -> mat_pure::Options {
let mut opts = mat_pure::Options::with_modern_strings();
opts.compression = self.compression.to_pure();
opts.invalid_name_policy = self.invalid_name_policy.to_pure();
opts.null_policy = self.null_policy.to_pure();
opts.unsupported_policy = self.unsupported_policy.to_pure();
opts.one_dimensional_mode = self.one_dimensional_mode.to_pure();
opts.row_major_policy = self.row_major_policy.to_pure();
opts.libver = self.libver.to_pure();
opts
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn every_variant_maps_to_its_upstream_twin() {
assert_eq!(Compression::None.to_pure(), mat_pure::Compression::None);
assert_eq!(
Compression::Deflate {
level: 6,
shuffle: true
}
.to_pure(),
mat_pure::Compression::Deflate {
level: 6,
shuffle: true
}
);
assert_eq!(
InvalidNamePolicy::Error.to_pure(),
mat_pure::InvalidNamePolicy::Error
);
assert_eq!(
InvalidNamePolicy::Sanitize.to_pure(),
mat_pure::InvalidNamePolicy::Sanitize
);
assert_eq!(
NullPolicy::EmptyStructArray.to_pure(),
mat_pure::NullPolicy::EmptyStructArray
);
assert_eq!(NullPolicy::Omit.to_pure(), mat_pure::NullPolicy::Omit);
assert_eq!(NullPolicy::Error.to_pure(), mat_pure::NullPolicy::Error);
assert_eq!(
UnsupportedPolicy::Error.to_pure(),
mat_pure::UnsupportedPolicy::Error
);
assert_eq!(
UnsupportedPolicy::StringFallback.to_pure(),
mat_pure::UnsupportedPolicy::StringFallback
);
assert_eq!(
UnsupportedPolicy::LossyNumericWidening.to_pure(),
mat_pure::UnsupportedPolicy::LossyNumericWidening
);
assert_eq!(
OneDimensionalMode::ColumnVector.to_pure(),
mat_pure::OneDimensionalMode::ColumnVector
);
assert_eq!(
OneDimensionalMode::RowVector.to_pure(),
mat_pure::OneDimensionalMode::RowVector
);
assert_eq!(
RowMajorPolicy::ReorderToColumnMajor.to_pure(),
mat_pure::RowMajorPolicy::ReorderToColumnMajor
);
assert_eq!(
RowMajorPolicy::Error.to_pure(),
mat_pure::RowMajorPolicy::Error
);
assert_eq!(LibVer::Earliest.to_pure(), hdf5_pure::LibVer::Earliest);
assert_eq!(LibVer::V18.to_pure(), hdf5_pure::LibVer::V18);
assert_eq!(LibVer::V110.to_pure(), hdf5_pure::LibVer::V110);
assert_eq!(LibVer::V112.to_pure(), hdf5_pure::LibVer::V112);
assert_eq!(LibVer::V114.to_pure(), hdf5_pure::LibVer::V114);
let ours = [
LibVer::Earliest,
LibVer::V18,
LibVer::V110,
LibVer::V112,
LibVer::V114,
];
assert!(ours.is_sorted(), "beve's LibVer is not oldest to newest");
assert!(
ours.map(LibVer::to_pure).is_sorted(),
"beve's LibVer ordering disagrees with hdf5-pure's"
);
}
#[test]
fn an_options_blob_stored_before_libver_existed_still_loads() {
let stored = r#"{"compression":"None","invalid_name_policy":"Error",
"null_policy":"EmptyStructArray","unsupported_policy":"Error",
"one_dimensional_mode":"ColumnVector",
"row_major_policy":"ReorderToColumnMajor"}"#;
let loaded: MatV73Options = serde_json::from_str(stored).unwrap();
assert_eq!(loaded, MatV73Options::default());
assert_eq!(loaded.libver, LibVer::V18);
}
#[test]
fn defaults_pin_modern_strings_and_the_matlab_readable_format() {
let opts = MatV73Options::default().to_pure();
assert_eq!(opts.string_class, mat_pure::StringClass::String);
assert_eq!(
opts.empty_marker_encoding,
mat_pure::EmptyMarkerEncoding::DataAsDims
);
assert_eq!(opts.libver, hdf5_pure::LibVer::V18);
assert_eq!(opts.compression, mat_pure::Compression::None);
}
}