use thiserror::Error;
pub type Result<T> = std::result::Result<T, TronError>;
#[derive(Error, Debug)]
pub enum TronError {
#[error("IO error: {0}")]
Io(#[from] std::io::Error),
#[error("Parse error: {0}")]
Parse(String),
#[error("Missing placeholder: {0}")]
MissingPlaceholder(String),
#[error("Invalid template syntax: {0}")]
InvalidSyntax(String),
#[error("Execution error: {0}")]
ExecutionError(String),
#[error("Validation error: {0}")]
ValidationError(String),
#[error("Cache error: {0}")]
CacheError(String),
}
impl TronError {
pub fn parse<S: Into<String>>(msg: S) -> Self {
TronError::Parse(msg.into())
}
pub fn validation<S: Into<String>>(msg: S) -> Self {
TronError::ValidationError(msg.into())
}
pub fn execution<S: Into<String>>(msg: S) -> Self {
TronError::ExecutionError(msg.into())
}
pub fn is_recoverable(&self) -> bool {
match self {
TronError::MissingPlaceholder(_) => true,
TronError::ExecutionError(_) => true,
TronError::CacheError(_) => true,
TronError::Io(_) => false,
TronError::Parse(_) => false,
TronError::InvalidSyntax(_) => false,
TronError::ValidationError(_) => false,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_error_creation() {
let parse_err = TronError::parse("test message");
assert!(matches!(parse_err, TronError::Parse(_)));
let validation_err = TronError::validation("validation failed");
assert!(matches!(validation_err, TronError::ValidationError(_)));
let execution_err = TronError::execution("execution failed");
assert!(matches!(execution_err, TronError::ExecutionError(_)));
}
#[test]
fn test_error_recoverability() {
assert!(TronError::MissingPlaceholder("test".to_string()).is_recoverable());
assert!(TronError::ExecutionError("test".to_string()).is_recoverable());
assert!(!TronError::InvalidSyntax("test".to_string()).is_recoverable());
assert!(!TronError::Parse("test".to_string()).is_recoverable());
}
}