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 Other { message: String },
82}
83
84impl fmt::Display for VxError {
85 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
86 match self {
87 VxError::ToolNotFound { tool_name } => {
88 write!(f, "Tool '{}' not found", tool_name)
89 }
90 VxError::ToolNotInstalled { tool_name } => {
91 write!(f, "Tool '{}' is not installed", tool_name)
92 }
93 VxError::VersionNotFound { tool_name, version } => {
94 write!(
95 f,
96 "Version '{}' not found for tool '{}'",
97 version, tool_name
98 )
99 }
100 VxError::InstallationFailed {
101 tool_name,
102 version,
103 message,
104 } => {
105 write!(
106 f,
107 "Failed to install {} {}: {}",
108 tool_name, version, message
109 )
110 }
111 VxError::VersionAlreadyInstalled { tool_name, version } => {
112 write!(
113 f,
114 "Version '{}' of tool '{}' is already installed",
115 version, tool_name
116 )
117 }
118 VxError::VersionNotInstalled { tool_name, version } => {
119 write!(
120 f,
121 "Version '{}' of tool '{}' is not installed",
122 version, tool_name
123 )
124 }
125 VxError::DownloadUrlNotFound { tool_name, version } => {
126 write!(f, "Download URL not found for {} {}", tool_name, version)
127 }
128 VxError::DownloadFailed { url, reason } => {
129 write!(f, "Failed to download from {}: {}", url, reason)
130 }
131 VxError::ConfigurationError { message } => {
132 write!(f, "Configuration error: {}", message)
133 }
134 VxError::ExecutableNotFound {
135 tool_name,
136 install_dir,
137 } => {
138 write!(
139 f,
140 "Executable for '{}' not found in {}",
141 tool_name,
142 install_dir.display()
143 )
144 }
145 VxError::ConfigError { message } => {
146 write!(f, "Configuration error: {}", message)
147 }
148 VxError::IoError { message } => {
149 write!(f, "IO error: {}", message)
150 }
151 VxError::NetworkError { message } => {
152 write!(f, "Network error: {}", message)
153 }
154 VxError::ParseError { message } => {
155 write!(f, "Parse error: {}", message)
156 }
157 VxError::PluginError {
158 plugin_name,
159 message,
160 } => {
161 write!(f, "Plugin '{}' error: {}", plugin_name, message)
162 }
163 VxError::PackageManagerError { manager, message } => {
164 write!(f, "Package manager '{}' error: {}", manager, message)
165 }
166 VxError::PermissionError { message } => {
167 write!(f, "Permission error: {}", message)
168 }
169 VxError::ChecksumError { expected, actual } => {
170 write!(
171 f,
172 "Checksum verification failed: expected {}, got {}",
173 expected, actual
174 )
175 }
176 VxError::UnsupportedOperation { operation, reason } => {
177 write!(f, "Unsupported operation '{}': {}", operation, reason)
178 }
179 VxError::Other { message } => {
180 write!(f, "{}", message)
181 }
182 }
183 }
184}
185
186impl std::error::Error for VxError {}
187
188impl From<std::io::Error> for VxError {
190 fn from(err: std::io::Error) -> Self {
191 VxError::IoError {
192 message: err.to_string(),
193 }
194 }
195}
196
197impl From<reqwest::Error> for VxError {
198 fn from(err: reqwest::Error) -> Self {
199 VxError::NetworkError {
200 message: err.to_string(),
201 }
202 }
203}
204
205impl From<serde_json::Error> for VxError {
206 fn from(err: serde_json::Error) -> Self {
207 VxError::ParseError {
208 message: err.to_string(),
209 }
210 }
211}
212
213impl From<toml::de::Error> for VxError {
214 fn from(err: toml::de::Error) -> Self {
215 VxError::ParseError {
216 message: err.to_string(),
217 }
218 }
219}
220
221impl From<anyhow::Error> for VxError {
222 fn from(err: anyhow::Error) -> Self {
223 VxError::Other {
224 message: err.to_string(),
225 }
226 }
227}
228
229impl From<walkdir::Error> for VxError {
230 fn from(err: walkdir::Error) -> Self {
231 VxError::IoError {
232 message: err.to_string(),
233 }
234 }
235}
236
237#[macro_export]
239macro_rules! tool_not_found {
240 ($tool:expr) => {
241 VxError::ToolNotFound {
242 tool_name: $tool.to_string(),
243 }
244 };
245}
246
247#[macro_export]
248macro_rules! tool_not_installed {
249 ($tool:expr) => {
250 VxError::ToolNotInstalled {
251 tool_name: $tool.to_string(),
252 }
253 };
254}
255
256#[macro_export]
257macro_rules! version_not_found {
258 ($tool:expr, $version:expr) => {
259 VxError::VersionNotFound {
260 tool_name: $tool.to_string(),
261 version: $version.to_string(),
262 }
263 };
264}