use std::path::PathBuf;
use thiserror::Error;
pub type ConfigResult<T> = Result<T, ConfigError>;
#[derive(Debug, Error, Clone)]
pub enum ConfigError {
#[error("Configuration file not found: {path}")]
NotFound {
path: PathBuf,
},
#[error("Failed to parse configuration file '{path}': {reason}")]
ParseError {
path: PathBuf,
reason: String,
},
#[error("Invalid configuration: {message}")]
InvalidConfig {
message: String,
},
#[error("Configuration validation failed")]
ValidationFailed {
errors: Vec<String>,
},
#[error("Unsupported configuration format: {format}")]
UnsupportedFormat {
format: String,
},
#[error("I/O error during configuration operation: {reason}")]
Io {
reason: String,
},
#[error("Environment variable error for '{var_name}': {reason}")]
EnvVarError {
var_name: String,
reason: String,
},
#[error("Configuration merge conflict in field '{field}': {reason}")]
MergeConflict {
field: String,
reason: String,
},
#[error("Invalid configuration path '{path}': {reason}")]
InvalidPath {
path: PathBuf,
reason: String,
},
#[error("Missing required configuration field: {field}")]
MissingField {
field: String,
},
#[error("Invalid type for configuration field '{field}': expected {expected}, got {actual}")]
InvalidFieldType {
field: String,
expected: String,
actual: String,
},
#[error("Permission denied for configuration file: {path}")]
PermissionDenied {
path: PathBuf,
},
#[error("Circular dependency detected in configuration: {cycle}")]
CircularDependency {
cycle: String,
},
}
impl AsRef<str> for ConfigError {
fn as_ref(&self) -> &str {
match self {
Self::NotFound { .. } => "configuration file not found",
Self::ParseError { .. } => "configuration parse error",
Self::InvalidConfig { .. } => "invalid configuration",
Self::ValidationFailed { .. } => "configuration validation failed",
Self::UnsupportedFormat { .. } => "unsupported configuration format",
Self::Io { .. } => "configuration I/O error",
Self::EnvVarError { .. } => "environment variable error",
Self::MergeConflict { .. } => "configuration merge conflict",
Self::InvalidPath { .. } => "invalid configuration path",
Self::MissingField { .. } => "missing required configuration field",
Self::InvalidFieldType { .. } => "invalid configuration field type",
Self::PermissionDenied { .. } => "configuration permission denied",
Self::CircularDependency { .. } => "circular configuration dependency",
}
}
}
impl ConfigError {
#[must_use]
pub fn count(&self) -> usize {
match self {
Self::ValidationFailed { errors } => errors.len(),
_ => 1,
}
}
#[must_use]
pub fn errors(&self) -> String {
match self {
Self::ValidationFailed { errors } => {
errors.iter().map(|e| format!(" - {}", e)).collect::<Vec<_>>().join("\n")
}
_ => self.to_string(),
}
}
}