1use serde::{Deserialize, Serialize};
4use std::fmt;
5use std::path::PathBuf;
6
7pub type Result<T> = std::result::Result<T, VxError>;
9
10#[derive(Debug, Clone, Serialize, Deserialize)]
12pub enum VxError {
13 ToolNotFound { tool_name: String },
15
16 ToolNotInstalled { tool_name: String },
18
19 VersionNotFound { tool_name: String, version: String },
21
22 InstallationFailed {
24 tool_name: String,
25 version: String,
26 message: String,
27 },
28
29 VersionAlreadyInstalled { tool_name: String, version: String },
31
32 VersionNotInstalled { tool_name: String, version: String },
34
35 DownloadUrlNotFound { tool_name: String, version: String },
37
38 DownloadFailed { url: String, reason: String },
40
41 ConfigurationError { message: String },
43
44 ExecutableNotFound {
46 tool_name: String,
47 install_dir: PathBuf,
48 },
49
50 ConfigError { message: String },
52
53 IoError { message: String },
55
56 NetworkError { message: String },
58
59 ParseError { message: String },
61
62 PluginError {
64 plugin_name: String,
65 message: String,
66 },
67
68 PackageManagerError { manager: String, message: String },
70
71 PermissionError { message: String },
73
74 ChecksumError { expected: String, actual: String },
76
77 UnsupportedOperation { operation: String, reason: String },
79
80 ShimNotFound(String),
82
83 Other { message: String },
85}
86
87impl fmt::Display for VxError {
88 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
89 match self {
90 VxError::ToolNotFound { tool_name } => {
91 write!(f, "Tool '{}' not found", tool_name)
92 }
93 VxError::ToolNotInstalled { tool_name } => {
94 write!(f, "Tool '{}' is not installed", tool_name)
95 }
96 VxError::VersionNotFound { tool_name, version } => {
97 write!(
98 f,
99 "Version '{}' not found for tool '{}'",
100 version, tool_name
101 )
102 }
103 VxError::InstallationFailed {
104 tool_name,
105 version,
106 message,
107 } => {
108 write!(
109 f,
110 "Failed to install {} {}: {}",
111 tool_name, version, message
112 )
113 }
114 VxError::VersionAlreadyInstalled { tool_name, version } => {
115 write!(
116 f,
117 "Version '{}' of tool '{}' is already installed",
118 version, tool_name
119 )
120 }
121 VxError::VersionNotInstalled { tool_name, version } => {
122 write!(
123 f,
124 "Version '{}' of tool '{}' is not installed",
125 version, tool_name
126 )
127 }
128 VxError::DownloadUrlNotFound { tool_name, version } => {
129 write!(f, "Download URL not found for {} {}", tool_name, version)
130 }
131 VxError::DownloadFailed { url, reason } => {
132 write!(f, "Failed to download from {}: {}", url, reason)
133 }
134 VxError::ConfigurationError { message } => {
135 write!(f, "Configuration error: {}", message)
136 }
137 VxError::ExecutableNotFound {
138 tool_name,
139 install_dir,
140 } => {
141 write!(
142 f,
143 "Executable for '{}' not found in {}",
144 tool_name,
145 install_dir.display()
146 )
147 }
148 VxError::ConfigError { message } => {
149 write!(f, "Configuration error: {}", message)
150 }
151 VxError::IoError { message } => {
152 write!(f, "IO error: {}", message)
153 }
154 VxError::NetworkError { message } => {
155 write!(f, "Network error: {}", message)
156 }
157 VxError::ParseError { message } => {
158 write!(f, "Parse error: {}", message)
159 }
160 VxError::PluginError {
161 plugin_name,
162 message,
163 } => {
164 write!(f, "Plugin '{}' error: {}", plugin_name, message)
165 }
166 VxError::PackageManagerError { manager, message } => {
167 write!(f, "Package manager '{}' error: {}", manager, message)
168 }
169 VxError::PermissionError { message } => {
170 write!(f, "Permission error: {}", message)
171 }
172 VxError::ChecksumError { expected, actual } => {
173 write!(
174 f,
175 "Checksum verification failed: expected {}, got {}",
176 expected, actual
177 )
178 }
179 VxError::UnsupportedOperation { operation, reason } => {
180 write!(f, "Unsupported operation '{}': {}", operation, reason)
181 }
182 VxError::ShimNotFound(message) => {
183 write!(f, "Shim not found: {}", message)
184 }
185 VxError::Other { message } => {
186 write!(f, "{}", message)
187 }
188 }
189 }
190}
191
192impl std::error::Error for VxError {}
193
194impl From<std::io::Error> for VxError {
196 fn from(err: std::io::Error) -> Self {
197 VxError::IoError {
198 message: err.to_string(),
199 }
200 }
201}
202
203impl From<reqwest::Error> for VxError {
204 fn from(err: reqwest::Error) -> Self {
205 VxError::NetworkError {
206 message: err.to_string(),
207 }
208 }
209}
210
211impl From<serde_json::Error> for VxError {
212 fn from(err: serde_json::Error) -> Self {
213 VxError::ParseError {
214 message: err.to_string(),
215 }
216 }
217}
218
219impl From<toml::de::Error> for VxError {
220 fn from(err: toml::de::Error) -> Self {
221 VxError::ParseError {
222 message: err.to_string(),
223 }
224 }
225}
226
227impl From<anyhow::Error> for VxError {
228 fn from(err: anyhow::Error) -> Self {
229 VxError::Other {
230 message: err.to_string(),
231 }
232 }
233}
234
235impl From<walkdir::Error> for VxError {
236 fn from(err: walkdir::Error) -> Self {
237 VxError::IoError {
238 message: err.to_string(),
239 }
240 }
241}
242
243#[macro_export]
245macro_rules! tool_not_found {
246 ($tool:expr) => {
247 VxError::ToolNotFound {
248 tool_name: $tool.to_string(),
249 }
250 };
251}
252
253#[macro_export]
254macro_rules! tool_not_installed {
255 ($tool:expr) => {
256 VxError::ToolNotInstalled {
257 tool_name: $tool.to_string(),
258 }
259 };
260}
261
262#[macro_export]
263macro_rules! version_not_found {
264 ($tool:expr, $version:expr) => {
265 VxError::VersionNotFound {
266 tool_name: $tool.to_string(),
267 version: $version.to_string(),
268 }
269 };
270}