use std::path::PathBuf;
use thiserror::Error;
pub type Result<T> = std::result::Result<T, CoreError>;
#[derive(Error, Debug)]
pub enum CoreError {
#[error("Configuration error: {message}")]
Config {
message: String,
#[source]
source: Option<Box<dyn std::error::Error + Send + Sync>>,
},
#[error("Parse error in {path}: {message}")]
Parse { path: PathBuf, message: String },
#[error("Frontmatter error in {path}: {message}")]
Frontmatter { path: PathBuf, message: String },
#[error("Template error: {0}")]
Template(String),
#[error("Search error: {0}")]
Search(String),
#[error("IO error: {0}")]
Io(#[from] std::io::Error),
#[error("TOML parse error: {0}")]
Toml(#[from] toml::de::Error),
#[error("YAML parse error: {0}")]
Yaml(#[from] serde_yaml::Error),
#[error("Config crate error: {0}")]
ConfigCrate(#[from] config::ConfigError),
}
impl CoreError {
pub fn config(message: impl Into<String>) -> Self {
Self::Config {
message: message.into(),
source: None,
}
}
pub fn config_with_source(
message: impl Into<String>,
source: impl std::error::Error + Send + Sync + 'static,
) -> Self {
Self::Config {
message: message.into(),
source: Some(Box::new(source)),
}
}
pub fn parse(path: impl Into<PathBuf>, message: impl Into<String>) -> Self {
Self::Parse {
path: path.into(),
message: message.into(),
}
}
pub fn frontmatter(path: impl Into<PathBuf>, message: impl Into<String>) -> Self {
Self::Frontmatter {
path: path.into(),
message: message.into(),
}
}
pub fn template(message: impl Into<String>) -> Self {
Self::Template(message.into())
}
pub fn search(message: impl Into<String>) -> Self {
Self::Search(message.into())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_config_error() {
let err = CoreError::config("missing field");
assert!(err.to_string().contains("Configuration error"));
assert!(err.to_string().contains("missing field"));
}
#[test]
fn test_parse_error() {
let err = CoreError::parse("content/post.md", "invalid syntax");
assert!(err.to_string().contains("Parse error"));
assert!(err.to_string().contains("content/post.md"));
}
#[test]
fn test_frontmatter_error() {
let err = CoreError::frontmatter("content/post.md", "missing title");
assert!(err.to_string().contains("Frontmatter error"));
assert!(err.to_string().contains("missing title"));
}
#[test]
fn test_io_error_conversion() {
let io_err = std::io::Error::new(std::io::ErrorKind::NotFound, "file not found");
let err: CoreError = io_err.into();
assert!(err.to_string().contains("IO error"));
}
}