use std::io;
use thiserror::Error;
#[derive(Error, Debug)]
#[non_exhaustive]
pub enum EngineError {
#[error("I/O error: {0}")]
Io(#[from] io::Error),
#[error("Request error: {0}")]
Reqwest(#[from] reqwest::Error),
#[error("Render error: {0}")]
Render(String),
#[error("Invalid template: {0}")]
InvalidTemplate(String),
#[error("Template error: {0}")]
Template(#[from] TemplateError),
#[error("Resource not found: {0}")]
ResourceNotFound(String),
#[error("Operation timed out: {0}")]
Timeout(String),
}
#[derive(Error, Debug)]
#[non_exhaustive]
pub enum TemplateError {
#[error("I/O error: {0}")]
Io(#[from] io::Error),
#[error("Request error: {0}")]
Reqwest(#[from] reqwest::Error),
#[error("Invalid template syntax: {0}")]
InvalidSyntax(String),
#[error("Rendering error: {0}")]
RenderError(String),
#[error("Engine error: {0}")]
EngineError(#[from] Box<EngineError>),
#[error("Missing variable: {0}")]
MissingVariable(String),
#[error("Invalid operation: {0}")]
InvalidOperation(String),
}
pub type Result<T> = std::result::Result<T, EngineError>;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_engine_error_display() {
let err = EngineError::Render(
"Failed to render template".to_string(),
);
assert_eq!(
err.to_string(),
"Render error: Failed to render template"
);
}
#[test]
fn test_template_error_display() {
let err =
TemplateError::InvalidSyntax("Unclosed tag".to_string());
assert_eq!(
err.to_string(),
"Invalid template syntax: Unclosed tag"
);
}
#[test]
fn test_error_conversion() {
let io_err =
io::Error::new(io::ErrorKind::NotFound, "File not found");
let engine_err: EngineError = io_err.into();
assert!(matches!(engine_err, EngineError::Io(_)));
}
#[test]
fn test_resource_not_found_error() {
let err =
EngineError::ResourceNotFound("template.html".to_string());
assert_eq!(
err.to_string(),
"Resource not found: template.html"
);
}
#[test]
fn test_timeout_error() {
let err = EngineError::Timeout(
"Fetching remote template".to_string(),
);
assert_eq!(
err.to_string(),
"Operation timed out: Fetching remote template"
);
}
#[test]
fn test_missing_variable_error() {
let err =
TemplateError::MissingVariable("user_name".to_string());
assert_eq!(err.to_string(), "Missing variable: user_name");
}
#[test]
fn test_invalid_operation_error() {
let err = TemplateError::InvalidOperation(
"Nested templates not allowed".to_string(),
);
assert_eq!(
err.to_string(),
"Invalid operation: Nested templates not allowed"
);
}
#[test]
fn test_engine_error_io() {
let io_err =
io::Error::new(io::ErrorKind::NotFound, "File not found");
let err = EngineError::Io(io_err);
assert_eq!(err.to_string(), "I/O error: File not found");
}
#[test]
fn test_engine_error_render() {
let err = EngineError::Render(
"Failed to render template".to_string(),
);
assert_eq!(
err.to_string(),
"Render error: Failed to render template"
);
}
#[test]
fn test_engine_error_invalid_template() {
let err =
EngineError::InvalidTemplate("Invalid syntax".to_string());
assert_eq!(err.to_string(), "Invalid template: Invalid syntax");
}
#[test]
fn test_engine_error_template() {
let template_err =
TemplateError::InvalidSyntax("Unclosed tag".to_string());
let err = EngineError::Template(template_err);
assert_eq!(
err.to_string(),
"Template error: Invalid template syntax: Unclosed tag"
);
}
#[test]
fn test_engine_error_resource_not_found() {
let err =
EngineError::ResourceNotFound("template.html".to_string());
assert_eq!(
err.to_string(),
"Resource not found: template.html"
);
}
#[test]
fn test_engine_error_timeout() {
let err = EngineError::Timeout(
"Fetching remote template".to_string(),
);
assert_eq!(
err.to_string(),
"Operation timed out: Fetching remote template"
);
}
#[test]
fn test_template_error_io() {
let io_err = io::Error::new(
io::ErrorKind::PermissionDenied,
"Permission denied",
);
let err = TemplateError::Io(io_err);
assert_eq!(err.to_string(), "I/O error: Permission denied");
}
#[test]
fn test_template_error_invalid_syntax() {
let err =
TemplateError::InvalidSyntax("Unclosed tag".to_string());
assert_eq!(
err.to_string(),
"Invalid template syntax: Unclosed tag"
);
}
#[test]
fn test_template_error_render_error() {
let err = TemplateError::RenderError(
"Missing context variable".to_string(),
);
assert_eq!(
err.to_string(),
"Rendering error: Missing context variable"
);
}
#[test]
fn test_template_error_engine_error() {
let engine_err =
EngineError::Render("Render failure".to_string());
let err = TemplateError::EngineError(Box::new(engine_err));
assert_eq!(
err.to_string(),
"Engine error: Render error: Render failure"
);
}
#[test]
fn test_template_error_missing_variable() {
let err =
TemplateError::MissingVariable("user_name".to_string());
assert_eq!(err.to_string(), "Missing variable: user_name");
}
#[test]
fn test_template_error_invalid_operation() {
let err = TemplateError::InvalidOperation(
"Nested templates not allowed".to_string(),
);
assert_eq!(
err.to_string(),
"Invalid operation: Nested templates not allowed"
);
}
#[test]
fn test_engine_error_conversion_from_io_error() {
let io_err =
io::Error::new(io::ErrorKind::NotFound, "File not found");
let engine_err: EngineError = io_err.into();
assert!(matches!(engine_err, EngineError::Io(_)));
}
#[test]
fn test_template_error_conversion_from_io_error() {
let io_err = io::Error::new(
io::ErrorKind::PermissionDenied,
"Permission denied",
);
let template_err: TemplateError = io_err.into();
assert!(matches!(template_err, TemplateError::Io(_)));
}
}