1use std::{fs, path::Path};
3
4use crate::e_target::{CargoTarget, TargetKind, TargetOrigin};
5use anyhow::{Context, Result};
6
7pub fn discover_targets(current_dir: &Path) -> Result<Vec<CargoTarget>> {
10 let mut targets = Vec::new();
11
12 let manifest_path = current_dir.join("Cargo.toml");
14 if manifest_path.exists() {
15 targets.push(CargoTarget {
16 name: "default".to_string(),
17 display_name: "Default Manifest".to_string(),
18 manifest_path: manifest_path.to_string_lossy().to_string(),
19 kind: TargetKind::Manifest,
20 extended: false,
21 origin: None,
22 });
23 }
24
25 let examples_dir = current_dir.join("examples");
27 if examples_dir.exists() && examples_dir.is_dir() {
28 for entry in fs::read_dir(&examples_dir)
29 .with_context(|| format!("Reading directory {:?}", examples_dir))?
30 {
31 let entry = entry?;
32 let path = entry.path();
33 if path.is_file() {
34 if let Some(ext) = path.extension() {
36 if ext == "rs" {
37 if let Some(stem) = path.file_stem() {
38 targets.push(CargoTarget {
39 name: stem.to_string_lossy().to_string(),
40 display_name: stem.to_string_lossy().to_string(),
41 manifest_path: current_dir
42 .join("Cargo.toml")
43 .to_string_lossy()
44 .to_string(),
45 kind: TargetKind::Example,
46 extended: false,
47 origin: Some(TargetOrigin::SingleFile(path)),
48 });
49 }
50 }
51 }
52 } else if path.is_dir() {
53 let sub_manifest = path.join("Cargo.toml");
55 if sub_manifest.exists() {
56 if let Some(name) = path.file_name() {
57 targets.push(CargoTarget {
58 name: name.to_string_lossy().to_string(),
59 display_name: name.to_string_lossy().to_string(),
60 manifest_path: sub_manifest.to_string_lossy().to_string(),
61 kind: TargetKind::Example,
62 extended: true,
63 origin: Some(TargetOrigin::SubProject(sub_manifest)),
64 });
65 }
66 }
67 }
68 }
69 }
70
71 Ok(targets)
74}
75
76#[cfg(test)]
77mod tests {
78 use super::*;
79 use std::fs;
80 use tempfile::tempdir;
81
82 #[test]
83 fn test_discover_targets_no_manifest() {
84 let temp = tempdir().unwrap();
85 let targets = discover_targets(temp.path()).unwrap();
87 assert!(targets.is_empty());
88 }
89
90 #[test]
91 fn test_discover_targets_with_manifest_and_example() {
92 let temp = tempdir().unwrap();
93 let manifest_path = temp.path().join("Cargo.toml");
95 fs::write(&manifest_path, "[package]\nname = \"dummy\"\n").unwrap();
96
97 let examples_dir = temp.path().join("examples");
99 fs::create_dir(&examples_dir).unwrap();
100 let example_file = examples_dir.join("example1.rs");
101 fs::write(&example_file, "fn main() {}").unwrap();
102
103 let targets = discover_targets(temp.path()).unwrap();
104 assert!(targets.len() >= 2);
106
107 let example_target = targets
108 .iter()
109 .find(|t| t.kind == TargetKind::Example && t.name == "example1");
110 assert!(example_target.is_some());
111 }
112}