use std::error::Error as StdError;
use std::fmt;
#[derive(Debug)]
pub enum DatarustError {
NotFitted(String),
InvalidInput(String),
ShapeMismatch {
expected: String,
actual: String,
},
EmptyInput(String),
AllMissing(String),
UnknownCategory(String),
UnknownLabel(String),
InvalidConfig(String),
Singular(String),
Io(std::io::Error),
#[cfg(feature = "serde")]
Serde(serde_json::Error),
}
impl fmt::Display for DatarustError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
DatarustError::NotFitted(s) => write!(f, "transformer not fitted: {}", s),
DatarustError::InvalidInput(s) => write!(f, "invalid input: {}", s),
DatarustError::ShapeMismatch { expected, actual } => {
write!(f, "shape mismatch: expected {}, got {}", expected, actual)
}
DatarustError::EmptyInput(s) => write!(f, "empty input: {}", s),
DatarustError::AllMissing(s) => write!(f, "all values missing: {}", s),
DatarustError::UnknownCategory(s) => write!(f, "unknown category: {}", s),
DatarustError::UnknownLabel(s) => write!(f, "unknown label: {}", s),
DatarustError::InvalidConfig(s) => write!(f, "invalid configuration: {}", s),
DatarustError::Singular(s) => write!(f, "singular/unstable operation: {}", s),
DatarustError::Io(e) => write!(f, "io error: {}", e),
#[cfg(feature = "serde")]
DatarustError::Serde(e) => write!(f, "serialization error: {}", e),
}
}
}
impl StdError for DatarustError {
fn source(&self) -> Option<&(dyn StdError + 'static)> {
match self {
DatarustError::Io(e) => Some(e),
#[cfg(feature = "serde")]
DatarustError::Serde(e) => Some(e),
_ => None,
}
}
}
impl From<std::io::Error> for DatarustError {
fn from(e: std::io::Error) -> Self {
DatarustError::Io(e)
}
}
#[cfg(feature = "serde")]
impl From<serde_json::Error> for DatarustError {
fn from(e: serde_json::Error) -> Self {
DatarustError::Serde(e)
}
}
pub type Result<T> = std::result::Result<T, DatarustError>;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn display_messages() {
assert_eq!(
DatarustError::NotFitted("scaler".into()).to_string(),
"transformer not fitted: scaler"
);
}
#[test]
fn shape_mismatch_display() {
let e = DatarustError::ShapeMismatch {
expected: "2 columns".into(),
actual: "3 columns".into(),
};
assert_eq!(
e.to_string(),
"shape mismatch: expected 2 columns, got 3 columns"
);
}
#[test]
fn from_io_error() {
let io_err = std::io::Error::new(std::io::ErrorKind::NotFound, "missing");
let e: DatarustError = io_err.into();
assert!(matches!(e, DatarustError::Io(_)));
assert!(e.source().is_some());
}
#[cfg(feature = "serde")]
#[test]
fn from_serde_error() {
let serde_err = serde_json::from_str::<()>("").unwrap_err();
let e: DatarustError = serde_err.into();
assert!(matches!(e, DatarustError::Serde(_)));
assert!(e.source().is_some());
}
}