use std::fmt;
pub type Result<T> = std::result::Result<T, VersionError>;
#[derive(Debug)]
pub enum VersionError {
InvalidVersion { version: String, reason: String },
NetworkError { url: String, source: reqwest::Error },
ParseError {
content: String,
source: serde_json::Error,
},
VersionNotFound { version: String, tool: String },
ToolNotFound { tool: String },
CommandError {
command: String,
source: std::io::Error,
},
Other { message: String },
}
impl fmt::Display for VersionError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
VersionError::InvalidVersion { version, reason } => {
write!(f, "Invalid version '{}': {}", version, reason)
}
VersionError::NetworkError { url, source } => {
write!(f, "Network error fetching from '{}': {}", url, source)
}
VersionError::ParseError { content, source } => {
write!(f, "Failed to parse content '{}': {}", content, source)
}
VersionError::VersionNotFound { version, tool } => {
write!(f, "Version '{}' not found for tool '{}'", version, tool)
}
VersionError::ToolNotFound { tool } => {
write!(f, "Tool '{}' not found in system", tool)
}
VersionError::CommandError { command, source } => {
write!(f, "Command '{}' failed: {}", command, source)
}
VersionError::Other { message } => {
write!(f, "{}", message)
}
}
}
}
impl std::error::Error for VersionError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
VersionError::NetworkError { source, .. } => Some(source),
VersionError::ParseError { source, .. } => Some(source),
VersionError::CommandError { source, .. } => Some(source),
_ => None,
}
}
}
impl From<reqwest::Error> for VersionError {
fn from(err: reqwest::Error) -> Self {
VersionError::NetworkError {
url: err
.url()
.map(|u| u.to_string())
.unwrap_or_else(|| "unknown".to_string()),
source: err,
}
}
}
impl From<serde_json::Error> for VersionError {
fn from(err: serde_json::Error) -> Self {
VersionError::ParseError {
content: "unknown".to_string(),
source: err,
}
}
}
impl From<std::io::Error> for VersionError {
fn from(err: std::io::Error) -> Self {
VersionError::CommandError {
command: "unknown".to_string(),
source: err,
}
}
}
impl From<anyhow::Error> for VersionError {
fn from(err: anyhow::Error) -> Self {
VersionError::Other {
message: err.to_string(),
}
}
}