1use std::fmt;
4
5pub type Result<T> = std::result::Result<T, VersionError>;
7
8#[derive(Debug)]
10pub enum VersionError {
11 InvalidVersion { version: String, reason: String },
13
14 NetworkError { url: String, source: reqwest::Error },
16
17 ParseError {
19 content: String,
20 source: serde_json::Error,
21 },
22
23 VersionNotFound { version: String, tool: String },
25
26 ToolNotFound { tool: String },
28
29 CommandError {
31 command: String,
32 source: std::io::Error,
33 },
34
35 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
78impl 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}