use std::fmt;
use std::path::PathBuf;
#[derive(Debug)]
#[non_exhaustive]
pub enum MattenDataError {
Csv {
message: String,
},
Io {
path: PathBuf,
source: std::io::Error,
},
EmptyInput,
MissingColumn {
name: String,
},
DuplicateColumn {
name: String,
},
DuplicateSelection {
name: String,
},
RaggedRow {
row: usize,
expected: usize,
actual: usize,
},
NonNumericValue {
column: String,
row: usize,
value: String,
},
MissingValue {
column: String,
row: usize,
},
EmptySelection,
Matten(matten::MattenError),
}
impl fmt::Display for MattenDataError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
MattenDataError::Csv { message } => {
write!(f, "matten-data CSV error: {message}")
}
MattenDataError::Io { path, source } => {
write!(
f,
"matten-data I/O error reading {}: {source}",
path.display()
)
}
MattenDataError::EmptyInput => {
write!(
f,
"matten-data error: input is empty (a header row is required)"
)
}
MattenDataError::MissingColumn { name } => {
write!(f, "matten-data error: column \"{name}\" does not exist")
}
MattenDataError::DuplicateColumn { name } => {
write!(f, "matten-data error: duplicate header column \"{name}\"")
}
MattenDataError::DuplicateSelection { name } => {
write!(
f,
"matten-data error: column \"{name}\" was selected more than once"
)
}
MattenDataError::RaggedRow {
row,
expected,
actual,
} => write!(
f,
"matten-data error: row {row} has {actual} cells but the header has {expected} columns"
),
MattenDataError::NonNumericValue { column, row, value } => write!(
f,
"matten-data numeric conversion error: column \"{column}\", row {row} contains \"{value}\", \
which cannot be converted to f64. Fill or clean the column before calling try_numeric()."
),
MattenDataError::MissingValue { column, row } => write!(
f,
"matten-data numeric conversion error: column \"{column}\", row {row} is missing. \
Fill missing values (e.g. with fill_missing) before calling try_numeric()."
),
MattenDataError::EmptySelection => {
write!(f, "matten-data error: no columns were selected")
}
MattenDataError::Matten(e) => write!(f, "matten-data error: {e}"),
}
}
}
impl std::error::Error for MattenDataError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
MattenDataError::Io { source, .. } => Some(source),
MattenDataError::Matten(e) => Some(e),
_ => None,
}
}
}
impl From<matten::MattenError> for MattenDataError {
fn from(e: matten::MattenError) -> Self {
MattenDataError::Matten(e)
}
}