use thiserror::Error;
#[derive(Error, Debug)]
pub enum XlsxToMdError {
#[error("IO error: {0}")]
Io(#[from] std::io::Error),
#[error("Failed to parse Excel file: {0}")]
Parse(#[from] calamine::Error),
#[error("UTF-8 conversion error: {0}")]
Utf8(#[from] std::str::Utf8Error),
#[error("ZIP archive error: {0}")]
Zip(String),
#[error("Number parse error: {0}")]
ParseInt(#[from] std::num::ParseIntError),
#[error("Configuration error: {0}")]
Config(String),
#[error("Unsupported feature at sheet '{sheet}', cell {cell}: {message}")]
UnsupportedFeature {
sheet: String,
cell: String,
message: String,
},
#[error("Security violation: {0}")]
SecurityViolation(String),
}
#[cfg(test)]
mod tests {
use super::*;
use std::io;
#[test]
fn test_io_error() {
let io_err = io::Error::new(io::ErrorKind::NotFound, "File not found");
let error: XlsxToMdError = io_err.into();
match error {
XlsxToMdError::Io(e) => {
assert_eq!(e.kind(), io::ErrorKind::NotFound);
assert_eq!(e.to_string(), "File not found");
}
_ => panic!("Expected Io error"),
}
}
#[test]
fn test_io_error_display() {
let io_err = io::Error::new(io::ErrorKind::PermissionDenied, "Permission denied");
let error: XlsxToMdError = io_err.into();
let error_msg = error.to_string();
assert!(error_msg.contains("IO error"));
assert!(error_msg.contains("Permission denied"));
}
#[test]
fn test_parse_error() {
let parse_err = calamine::Error::Msg("Invalid file format");
let error: XlsxToMdError = parse_err.into();
match error {
XlsxToMdError::Parse(e) => match e {
calamine::Error::Msg(msg) => {
assert_eq!(msg, "Invalid file format");
}
_ => panic!("Expected Msg variant"),
},
_ => panic!("Expected Parse error"),
}
}
#[test]
fn test_parse_error_display() {
let parse_err = calamine::Error::Msg("Corrupted file");
let error: XlsxToMdError = parse_err.into();
let error_msg = error.to_string();
assert!(error_msg.contains("Failed to parse Excel file"));
assert!(error_msg.contains("Corrupted file"));
}
#[test]
fn test_config_error() {
let error = XlsxToMdError::Config("Invalid range: start > end".to_string());
match error {
XlsxToMdError::Config(msg) => {
assert_eq!(msg, "Invalid range: start > end");
}
_ => panic!("Expected Config error"),
}
}
#[test]
fn test_config_error_display() {
let error = XlsxToMdError::Config("Invalid date format: 'xyz'".to_string());
let error_msg = error.to_string();
assert!(error_msg.contains("Configuration error"));
assert!(error_msg.contains("Invalid date format: 'xyz'"));
}
#[test]
fn test_unsupported_feature_error() {
let error = XlsxToMdError::UnsupportedFeature {
sheet: "Sheet1".to_string(),
cell: "A1".to_string(),
message: "Pivot table is not supported".to_string(),
};
match error {
XlsxToMdError::UnsupportedFeature {
sheet,
cell,
message,
} => {
assert_eq!(sheet, "Sheet1");
assert_eq!(cell, "A1");
assert_eq!(message, "Pivot table is not supported");
}
_ => panic!("Expected UnsupportedFeature error"),
}
}
#[test]
fn test_unsupported_feature_error_display() {
let error = XlsxToMdError::UnsupportedFeature {
sheet: "MySheet".to_string(),
cell: "B5".to_string(),
message: "Complex formula not supported in Phase I".to_string(),
};
let error_msg = error.to_string();
assert!(error_msg.contains("Unsupported feature"));
assert!(error_msg.contains("MySheet"));
assert!(error_msg.contains("B5"));
assert!(error_msg.contains("Complex formula not supported in Phase I"));
}
#[test]
fn test_error_conversion_with_question_mark() {
fn io_operation() -> Result<(), XlsxToMdError> {
let _file = std::fs::File::open("nonexistent_file.xlsx")?;
Ok(())
}
let result = io_operation();
assert!(result.is_err());
match result {
Err(XlsxToMdError::Io(_)) => {}
_ => panic!("Expected Io error from ? operator"),
}
}
#[test]
fn test_error_conversion_from_calamine() {
let parse_err = calamine::Error::Msg("File not found");
let error: XlsxToMdError = parse_err.into();
match error {
XlsxToMdError::Parse(_) => {}
_ => panic!("Expected Parse error"),
}
}
#[test]
fn test_all_error_formats() {
let io_err: XlsxToMdError = io::Error::other("test io").into();
assert!(io_err.to_string().starts_with("IO error"));
let parse_err: XlsxToMdError = calamine::Error::Msg("test parse").into();
assert!(parse_err
.to_string()
.starts_with("Failed to parse Excel file"));
let config_err = XlsxToMdError::Config("test config".to_string());
assert!(config_err.to_string().starts_with("Configuration error"));
let unsupported_err = XlsxToMdError::UnsupportedFeature {
sheet: "Sheet1".to_string(),
cell: "A1".to_string(),
message: "test unsupported".to_string(),
};
assert!(unsupported_err
.to_string()
.starts_with("Unsupported feature"));
}
}