use core::fmt;
use crate::error::{Error as Hdf5Error, FormatError};
#[derive(Debug)]
#[non_exhaustive]
pub enum MatError {
Hdf5(Hdf5Error),
Format(FormatError),
Io(std::io::Error),
RootMustBeStruct,
UnsupportedType(&'static str),
MixedSequenceElementTypes,
RaggedMatrix {
expected: usize,
got: usize,
},
ShapeMismatch {
expected: String,
actual: String,
},
MissingField(String),
UnknownClass(String),
UnsupportedMatlabClass(String),
Utf16Decode(String),
Custom(String),
}
impl fmt::Display for MatError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
MatError::Hdf5(e) => write!(f, "HDF5 error: {e}"),
MatError::Format(e) => write!(f, "HDF5 format error: {e}"),
MatError::Io(e) => write!(f, "I/O error: {e}"),
MatError::RootMustBeStruct => write!(
f,
"top-level value must be a struct with named fields; each field becomes a MATLAB variable"
),
MatError::UnsupportedType(t) => write!(f, "unsupported Rust type for MAT v7.3: {t}"),
MatError::MixedSequenceElementTypes => write!(
f,
"sequence elements have mixed primitive types; all elements of a numeric array must share a type"
),
MatError::RaggedMatrix { expected, got } => write!(
f,
"ragged 2-D matrix: expected row length {expected}, got {got}"
),
MatError::ShapeMismatch { expected, actual } => {
write!(f, "shape mismatch: expected {expected}, got {actual}")
}
MatError::MissingField(name) => write!(f, "missing required field: {name}"),
MatError::UnknownClass(c) => write!(f, "unknown MATLAB_class: {c:?}"),
MatError::UnsupportedMatlabClass(c) => write!(
f,
"MATLAB class {c:?} is not yet supported for reading (modern `string` is; \
other MCOS opaque classes such as datetime/categorical/table are refused for now)"
),
MatError::Utf16Decode(msg) => write!(f, "UTF-16 decode: {msg}"),
MatError::Custom(msg) => write!(f, "{msg}"),
}
}
}
impl std::error::Error for MatError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
MatError::Hdf5(e) => Some(e),
MatError::Format(e) => Some(e),
MatError::Io(e) => Some(e),
_ => None,
}
}
}
impl From<Hdf5Error> for MatError {
fn from(e: Hdf5Error) -> Self {
MatError::Hdf5(e)
}
}
impl From<FormatError> for MatError {
fn from(e: FormatError) -> Self {
MatError::Format(e)
}
}
impl From<std::io::Error> for MatError {
fn from(e: std::io::Error) -> Self {
MatError::Io(e)
}
}
#[cfg(feature = "serde")]
impl serde::ser::Error for MatError {
fn custom<T: fmt::Display>(msg: T) -> Self {
MatError::Custom(msg.to_string())
}
}
#[cfg(feature = "serde")]
impl serde::de::Error for MatError {
fn custom<T: fmt::Display>(msg: T) -> Self {
MatError::Custom(msg.to_string())
}
}