use thiserror::Error;
#[derive(Error, Debug)]
pub enum SMirrorsError {
#[error("Failed to detect distribution")]
DistroDetectionFailed,
#[error("Unsupported distribution: {0}")]
UnsupportedDistro(String),
#[error("Mirror test failed for {url}: {reason}")]
MirrorTestFailed { url: String, reason: String },
#[error("Permission denied: {0}. Try running with sudo")]
PermissionDenied(String),
#[error("Configuration error: {0}")]
ConfigError(String),
#[error("Invalid configuration value for {key}: {value}")]
InvalidConfigValue { key: String, value: String },
#[error("Configuration file not found at {0}")]
ConfigNotFound(String),
#[error("IO error: {0}")]
IoError(#[from] std::io::Error),
#[error("Network error: {0}")]
NetworkError(#[from] reqwest::Error),
#[error("Database error: {0}")]
DatabaseError(#[from] rusqlite::Error),
#[error("Parse error: {0}")]
ParseError(String),
#[error("Regex error: {0}")]
RegexError(#[from] regex::Error),
#[error("URL parse error: {0}")]
UrlError(#[from] url::ParseError),
#[error("TOML deserialization error: {0}")]
TomlDeError(#[from] toml::de::Error),
#[error("TOML serialization error: {0}")]
TomlSerError(#[from] toml::ser::Error),
#[error("JSON error: {0}")]
JsonError(#[from] serde_json::Error),
#[error("Systemd error: {0}")]
SystemdError(String),
#[error("Backup not found: {0}")]
BackupNotFound(String),
#[error("Backup restore failed: {0}")]
BackupRestoreFailed(String),
#[error("Mirror list empty after filtering")]
NoMirrorsAvailable,
#[error("Test timeout after {0} seconds")]
TestTimeout(u64),
#[error("Update failed: {0}")]
UpdateFailed(String),
#[error("Validation failed: {0}")]
ValidationFailed(String),
#[error("Lock file exists at {0}. Another instance may be running")]
LockFileExists(String),
#[error("Async task join error: {0}")]
JoinError(#[from] tokio::task::JoinError),
}
impl SMirrorsError {
pub fn permission_denied(operation: &str) -> Self {
Self::PermissionDenied(operation.to_string())
}
pub fn config_error(message: impl Into<String>) -> Self {
Self::ConfigError(message.into())
}
pub fn parse_error(message: impl Into<String>) -> Self {
Self::ParseError(message.into())
}
pub fn systemd_error(message: impl Into<String>) -> Self {
Self::SystemdError(message.into())
}
pub fn update_failed(message: impl Into<String>) -> Self {
Self::UpdateFailed(message.into())
}
pub fn validation_failed(message: impl Into<String>) -> Self {
Self::ValidationFailed(message.into())
}
pub fn is_network_error(&self) -> bool {
matches!(self, Self::NetworkError(_) | Self::MirrorTestFailed { .. })
}
pub fn is_permission_error(&self) -> bool {
matches!(self, Self::PermissionDenied(_))
}
pub fn is_recoverable(&self) -> bool {
matches!(
self,
Self::NetworkError(_)
| Self::MirrorTestFailed { .. }
| Self::TestTimeout(_)
)
}
}