vx_version/
error.rs

1//! Error types for version management operations
2
3use std::fmt;
4
5/// Result type alias for version operations
6pub type Result<T> = std::result::Result<T, VersionError>;
7
8/// Error types that can occur during version operations
9#[derive(Debug)]
10pub enum VersionError {
11    /// Invalid version format
12    InvalidVersion { version: String, reason: String },
13
14    /// Network error during version fetching
15    NetworkError { url: String, source: reqwest::Error },
16
17    /// JSON parsing error
18    ParseError {
19        content: String,
20        source: serde_json::Error,
21    },
22
23    /// Version not found
24    VersionNotFound { version: String, tool: String },
25
26    /// Tool not found in system
27    ToolNotFound { tool: String },
28
29    /// Command execution error
30    CommandError {
31        command: String,
32        source: std::io::Error,
33    },
34
35    /// Generic error
36    Other { message: String },
37}
38
39impl fmt::Display for VersionError {
40    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41        match self {
42            VersionError::InvalidVersion { version, reason } => {
43                write!(f, "Invalid version '{}': {}", version, reason)
44            }
45            VersionError::NetworkError { url, source } => {
46                write!(f, "Network error fetching from '{}': {}", url, source)
47            }
48            VersionError::ParseError { content, source } => {
49                write!(f, "Failed to parse content '{}': {}", content, source)
50            }
51            VersionError::VersionNotFound { version, tool } => {
52                write!(f, "Version '{}' not found for tool '{}'", version, tool)
53            }
54            VersionError::ToolNotFound { tool } => {
55                write!(f, "Tool '{}' not found in system", tool)
56            }
57            VersionError::CommandError { command, source } => {
58                write!(f, "Command '{}' failed: {}", command, source)
59            }
60            VersionError::Other { message } => {
61                write!(f, "{}", message)
62            }
63        }
64    }
65}
66
67impl std::error::Error for VersionError {
68    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
69        match self {
70            VersionError::NetworkError { source, .. } => Some(source),
71            VersionError::ParseError { source, .. } => Some(source),
72            VersionError::CommandError { source, .. } => Some(source),
73            _ => None,
74        }
75    }
76}
77
78// Conversion from other error types
79impl From<reqwest::Error> for VersionError {
80    fn from(err: reqwest::Error) -> Self {
81        VersionError::NetworkError {
82            url: err
83                .url()
84                .map(|u| u.to_string())
85                .unwrap_or_else(|| "unknown".to_string()),
86            source: err,
87        }
88    }
89}
90
91impl From<serde_json::Error> for VersionError {
92    fn from(err: serde_json::Error) -> Self {
93        VersionError::ParseError {
94            content: "unknown".to_string(),
95            source: err,
96        }
97    }
98}
99
100impl From<std::io::Error> for VersionError {
101    fn from(err: std::io::Error) -> Self {
102        VersionError::CommandError {
103            command: "unknown".to_string(),
104            source: err,
105        }
106    }
107}
108
109impl From<anyhow::Error> for VersionError {
110    fn from(err: anyhow::Error) -> Self {
111        VersionError::Other {
112            message: err.to_string(),
113        }
114    }
115}