1use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
8use std::path::PathBuf;
9
10#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
12pub struct VersionInfo {
13 pub version: String,
15 pub prerelease: bool,
17 pub release_date: Option<String>,
19 pub release_notes: Option<String>,
21 pub download_url: Option<String>,
23 pub checksum: Option<String>,
25 pub file_size: Option<u64>,
27 pub metadata: HashMap<String, String>,
29}
30
31impl VersionInfo {
32 pub fn new(version: impl Into<String>) -> Self {
34 Self {
35 version: version.into(),
36 prerelease: false,
37 release_date: None,
38 release_notes: None,
39 download_url: None,
40 checksum: None,
41 file_size: None,
42 metadata: HashMap::new(),
43 }
44 }
45
46 pub fn with_url(version: impl Into<String>, download_url: impl Into<String>) -> Self {
48 Self {
49 version: version.into(),
50 prerelease: false,
51 release_date: None,
52 release_notes: None,
53 download_url: Some(download_url.into()),
54 checksum: None,
55 file_size: None,
56 metadata: HashMap::new(),
57 }
58 }
59
60 pub fn as_prerelease(mut self) -> Self {
62 self.prerelease = true;
63 self
64 }
65
66 pub fn with_release_date(mut self, date: impl Into<String>) -> Self {
68 self.release_date = Some(date.into());
69 self
70 }
71
72 pub fn with_release_notes(mut self, notes: impl Into<String>) -> Self {
74 self.release_notes = Some(notes.into());
75 self
76 }
77
78 pub fn with_checksum(mut self, checksum: impl Into<String>) -> Self {
80 self.checksum = Some(checksum.into());
81 self
82 }
83
84 pub fn with_file_size(mut self, size: u64) -> Self {
86 self.file_size = Some(size);
87 self
88 }
89
90 pub fn with_metadata(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
92 self.metadata.insert(key.into(), value.into());
93 self
94 }
95}
96
97#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
99pub struct PackageSpec {
100 pub name: String,
102 pub version: Option<String>,
104 pub features: Vec<String>,
106 pub dev_dependency: bool,
108 pub options: HashMap<String, String>,
110}
111
112impl PackageSpec {
113 pub fn new(name: impl Into<String>) -> Self {
115 Self {
116 name: name.into(),
117 version: None,
118 features: Vec::new(),
119 dev_dependency: false,
120 options: HashMap::new(),
121 }
122 }
123
124 pub fn with_version(mut self, version: impl Into<String>) -> Self {
126 self.version = Some(version.into());
127 self
128 }
129
130 pub fn with_feature(mut self, feature: impl Into<String>) -> Self {
132 self.features.push(feature.into());
133 self
134 }
135
136 pub fn as_dev_dependency(mut self) -> Self {
138 self.dev_dependency = true;
139 self
140 }
141}
142#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
144pub struct PackageInfo {
145 pub name: String,
147 pub version: String,
149 pub description: Option<String>,
151 pub dev_dependency: bool,
153 pub metadata: HashMap<String, String>,
155}
156
157#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
159pub enum Ecosystem {
160 Node,
162 Python,
164 Rust,
166 Go,
168 Java,
170 DotNet,
172 Ruby,
174 Php,
176 Generic,
178}
179
180impl std::fmt::Display for Ecosystem {
181 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
182 match self {
183 Ecosystem::Node => write!(f, "node"),
184 Ecosystem::Python => write!(f, "python"),
185 Ecosystem::Rust => write!(f, "rust"),
186 Ecosystem::Go => write!(f, "go"),
187 Ecosystem::Java => write!(f, "java"),
188 Ecosystem::DotNet => write!(f, "dotnet"),
189 Ecosystem::Ruby => write!(f, "ruby"),
190 Ecosystem::Php => write!(f, "php"),
191 Ecosystem::Generic => write!(f, "generic"),
192 }
193 }
194}
195
196#[derive(Debug, Clone, Default)]
198pub struct ToolContext {
199 pub working_directory: Option<PathBuf>,
201 pub environment_variables: HashMap<String, String>,
203 pub use_system_path: bool,
205 pub options: HashMap<String, String>,
207}
208
209impl ToolContext {
210 pub fn new() -> Self {
212 Self::default()
213 }
214
215 pub fn with_working_directory(mut self, dir: PathBuf) -> Self {
217 self.working_directory = Some(dir);
218 self
219 }
220
221 pub fn with_env(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
223 self.environment_variables.insert(key.into(), value.into());
224 self
225 }
226
227 pub fn with_system_path(mut self) -> Self {
229 self.use_system_path = true;
230 self
231 }
232}
233#[derive(Debug, Clone, PartialEq, Eq)]
235pub struct ToolExecutionResult {
236 pub exit_code: i32,
238 pub stdout: Option<String>,
240 pub stderr: Option<String>,
242}
243
244impl ToolExecutionResult {
245 pub fn success() -> Self {
247 Self {
248 exit_code: 0,
249 stdout: None,
250 stderr: None,
251 }
252 }
253
254 pub fn failure(exit_code: i32) -> Self {
256 Self {
257 exit_code,
258 stdout: None,
259 stderr: None,
260 }
261 }
262
263 pub fn is_success(&self) -> bool {
265 self.exit_code == 0
266 }
267
268 pub fn with_stdout(mut self, stdout: impl Into<String>) -> Self {
270 self.stdout = Some(stdout.into());
271 self
272 }
273
274 pub fn with_stderr(mut self, stderr: impl Into<String>) -> Self {
276 self.stderr = Some(stderr.into());
277 self
278 }
279}
280
281#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
283pub struct ToolStatus {
284 pub installed: bool,
286 pub current_version: Option<String>,
288 pub installed_versions: Vec<String>,
290}
291
292impl ToolStatus {
293 pub fn new() -> Self {
295 Self {
296 installed: false,
297 current_version: None,
298 installed_versions: Vec::new(),
299 }
300 }
301
302 pub fn installed_with_versions(versions: Vec<String>, current: Option<String>) -> Self {
304 Self {
305 installed: !versions.is_empty(),
306 current_version: current,
307 installed_versions: versions,
308 }
309 }
310}
311
312impl Default for ToolStatus {
313 fn default() -> Self {
314 Self::new()
315 }
316}
317
318#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
320pub struct ToolMetadata {
321 pub name: String,
323 pub description: String,
325 pub aliases: Vec<String>,
327 pub platforms: Vec<String>,
329 pub metadata: HashMap<String, String>,
331}
332
333impl ToolMetadata {
334 pub fn new(name: impl Into<String>, description: impl Into<String>) -> Self {
336 Self {
337 name: name.into(),
338 description: description.into(),
339 aliases: Vec::new(),
340 platforms: Vec::new(),
341 metadata: HashMap::new(),
342 }
343 }
344
345 pub fn with_alias(mut self, alias: impl Into<String>) -> Self {
347 self.aliases.push(alias.into());
348 self
349 }
350
351 pub fn with_platform(mut self, platform: impl Into<String>) -> Self {
353 self.platforms.push(platform.into());
354 self
355 }
356
357 pub fn with_metadata(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
359 self.metadata.insert(key.into(), value.into());
360 self
361 }
362}
363
364#[derive(Debug, Clone, Serialize, Deserialize)]
366pub struct PackageManagerConfig {
367 pub name: String,
369 pub version: Option<String>,
371 pub executable_path: Option<PathBuf>,
373 pub config_files: Vec<PathBuf>,
375 pub cache_directory: Option<PathBuf>,
377 pub supports_lockfiles: bool,
379 pub supports_workspaces: bool,
381 pub isolation_level: IsolationLevel,
383}
384
385#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
387pub enum IsolationLevel {
388 Global,
390 User,
392 #[default]
394 Project,
395 Sandbox,
397}