use std::error::Error;
use std::fmt;
#[derive(Debug)]
pub enum SqawkError {
IoError(std::io::Error),
CsvError(csv::Error),
CsvParseError {
file: String,
line: usize,
error: String,
},
SqlParseError(sqlparser::parser::ParserError),
TableNotFound(String),
TableAlreadyExists(String),
FileNotFound(String),
NoFilePath(String),
ColumnNotFound(String),
InvalidFileSpec(String),
UnsupportedSqlFeature(String),
InvalidSqlQuery(String),
VmError(String),
}
impl fmt::Display for SqawkError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
SqawkError::IoError(e) => write!(f, "I/O error: {}", e),
SqawkError::CsvError(e) => write!(f, "File parsing error: {}", e),
SqawkError::CsvParseError { file, line, error } => {
write!(f, "CSV parse error in {} at line {}: {}", file, line, error)
}
SqawkError::SqlParseError(e) => write!(f, "SQL parsing error: {}", e),
SqawkError::TableNotFound(name) => write!(f, "Table '{}' not found", name),
SqawkError::TableAlreadyExists(name) => write!(f, "Table '{}' already exists", name),
SqawkError::FileNotFound(path) => write!(f, "File not found: {}", path),
SqawkError::NoFilePath(name) => {
write!(f, "Table '{}' has no associated file path", name)
}
SqawkError::ColumnNotFound(name) => write!(f, "Column '{}' not found", name),
SqawkError::InvalidFileSpec(spec) => write!(f, "Invalid file specification: {}", spec),
SqawkError::UnsupportedSqlFeature(feature) => {
write!(f, "Unsupported SQL feature: {}", feature)
}
SqawkError::InvalidSqlQuery(msg) => write!(f, "Invalid SQL query: {}", msg),
SqawkError::VmError(msg) => write!(f, "VM execution error: {}", msg),
}
}
}
impl Error for SqawkError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
SqawkError::IoError(e) => Some(e),
SqawkError::CsvError(e) => Some(e),
SqawkError::SqlParseError(e) => Some(e),
_ => None,
}
}
}
impl From<std::io::Error> for SqawkError {
fn from(err: std::io::Error) -> Self {
SqawkError::IoError(err)
}
}
impl From<csv::Error> for SqawkError {
fn from(err: csv::Error) -> Self {
SqawkError::CsvError(err)
}
}
impl From<sqlparser::parser::ParserError> for SqawkError {
fn from(err: sqlparser::parser::ParserError) -> Self {
SqawkError::SqlParseError(err)
}
}
impl PartialEq for SqawkError {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(SqawkError::IoError(_), SqawkError::IoError(_)) => true,
(SqawkError::CsvError(_), SqawkError::CsvError(_)) => true,
(SqawkError::CsvParseError { .. }, SqawkError::CsvParseError { .. }) => true,
(SqawkError::SqlParseError(_), SqawkError::SqlParseError(_)) => true,
(SqawkError::TableNotFound(_), SqawkError::TableNotFound(_)) => true,
(SqawkError::TableAlreadyExists(_), SqawkError::TableAlreadyExists(_)) => true,
(SqawkError::FileNotFound(_), SqawkError::FileNotFound(_)) => true,
(SqawkError::NoFilePath(_), SqawkError::NoFilePath(_)) => true,
(SqawkError::ColumnNotFound(_), SqawkError::ColumnNotFound(_)) => true,
(SqawkError::InvalidFileSpec(_), SqawkError::InvalidFileSpec(_)) => true,
(SqawkError::UnsupportedSqlFeature(_), SqawkError::UnsupportedSqlFeature(_)) => true,
(SqawkError::InvalidSqlQuery(_), SqawkError::InvalidSqlQuery(_)) => true,
(SqawkError::VmError(_), SqawkError::VmError(_)) => true,
_ => false,
}
}
}
pub type SqawkResult<T> = std::result::Result<T, SqawkError>;