1use crate::core::{Artifact, ArtifactKind, ArtifactMetadata, MarkerKind, ProjectKind, ProjectMarker};
4use crate::error::Result;
5use crate::plugins::Plugin;
6use std::path::Path;
7
8pub struct RustPlugin;
10
11impl Plugin for RustPlugin {
12 fn id(&self) -> &'static str {
13 "rust"
14 }
15
16 fn name(&self) -> &'static str {
17 "Rust (Cargo)"
18 }
19
20 fn supported_kinds(&self) -> &[ProjectKind] {
21 &[ProjectKind::Rust]
22 }
23
24 fn markers(&self) -> Vec<ProjectMarker> {
25 vec![
26 ProjectMarker {
27 indicator: MarkerKind::File("Cargo.toml"),
28 kind: ProjectKind::Rust,
29 priority: 60,
30 },
31 ]
32 }
33
34 fn detect(&self, path: &Path) -> Option<ProjectKind> {
35 if path.join("Cargo.toml").is_file() {
36 Some(ProjectKind::Rust)
37 } else {
38 None
39 }
40 }
41
42 fn find_artifacts(&self, project_root: &Path) -> Result<Vec<Artifact>> {
43 let mut artifacts = Vec::new();
44
45 let target = project_root.join("target");
47 if target.exists() {
48 artifacts.push(Artifact {
49 path: target,
50 kind: ArtifactKind::BuildOutput,
51 size: 0,
52 file_count: 0,
53 age: None,
54 metadata: ArtifactMetadata {
55 restorable: true,
56 restore_command: Some("cargo build".into()),
57 lockfile: Some(project_root.join("Cargo.lock")),
58 restore_time_estimate: Some(60), ..Default::default()
60 },
61 });
62 }
63
64 Ok(artifacts)
68 }
69
70 fn cleanable_dirs(&self) -> &[&'static str] {
71 &["target"]
72 }
73
74 fn priority(&self) -> u8 {
75 60
76 }
77}
78
79#[cfg(test)]
80mod tests {
81 use super::*;
82 use tempfile::TempDir;
83
84 #[test]
85 fn test_detect_rust() {
86 let temp = TempDir::new().unwrap();
87 std::fs::write(
88 temp.path().join("Cargo.toml"),
89 r#"[package]
90name = "test"
91version = "0.1.0"
92"#,
93 )
94 .unwrap();
95
96 let plugin = RustPlugin;
97 assert_eq!(plugin.detect(temp.path()), Some(ProjectKind::Rust));
98 }
99
100 #[test]
101 fn test_no_detect_without_cargo() {
102 let temp = TempDir::new().unwrap();
103
104 let plugin = RustPlugin;
105 assert_eq!(plugin.detect(temp.path()), None);
106 }
107
108 #[test]
109 fn test_find_artifacts() {
110 let temp = TempDir::new().unwrap();
111 std::fs::write(temp.path().join("Cargo.toml"), "[package]").unwrap();
112 std::fs::create_dir(temp.path().join("target")).unwrap();
113
114 let plugin = RustPlugin;
115 let artifacts = plugin.find_artifacts(temp.path()).unwrap();
116
117 assert_eq!(artifacts.len(), 1);
118 assert_eq!(artifacts[0].name(), "target");
119 assert_eq!(artifacts[0].kind, ArtifactKind::BuildOutput);
120 }
121}