workspacer_workspace/
find_items.rs1crate::ix!();
3
4#[async_trait]
5impl<P, H> AsyncFindItems for Workspace<P, H>
6where
7 for<'async_trait> P: From<PathBuf> + AsRef<Path> + Send + Sync + 'async_trait,
9 H: CrateHandleInterface<P> + Send + Sync,
10{
11 type Item = Arc<AsyncMutex<H>>;
12 type Error = WorkspaceError;
13
14 async fn find_items(path: &Path) -> Result<Vec<Self::Item>, Self::Error> {
16 let mut crates = vec![];
17
18 let mut entries = fs::read_dir(path)
19 .await
20 .map_err(|e| DirectoryError::ReadDirError { io: e.into() })?;
21
22 while let Some(entry) = entries
23 .next_entry()
24 .await
25 .map_err(|e| DirectoryError::GetNextEntryError { io: e.into() })?
26 {
27 let crate_path = entry.path();
28
29 if fs::metadata(crate_path.join("Cargo.toml"))
31 .await
32 .is_ok()
33 {
34 let converted: P = crate_path.into();
36 crates.push(Arc::new(AsyncMutex::new(H::new(&converted).await?)));
37 }
38 }
39
40 Ok(crates)
41 }
42}
43
44#[cfg(test)]
45mod test_async_find_items {
46 use super::*;
47
48 type MyWorkspace = Workspace<PathBuf, CrateHandle>;
50
51 #[traced_test]
56 async fn test_find_items_in_directory() {
57 info!("Starting test_find_items_in_directory");
58 let tmp = tempdir().expect("Failed to create temp dir");
59 let root = tmp.path().to_path_buf();
60
61 let crate_a = root.join("crateA");
63 fs::create_dir(&crate_a).await.unwrap();
64 fs::write(crate_a.join("Cargo.toml"), b"[package]\nname=\"crateA\"").await.unwrap();
65
66 let crate_b = root.join("crateB");
67 fs::create_dir(&crate_b).await.unwrap();
68 fs::write(crate_b.join("Cargo.toml"), b"[package]\nname=\"crateB\"").await.unwrap();
69
70 let crates_found = MyWorkspace::find_items(&root).await
72 .expect("Should find both crates in subdirectories");
73
74 assert_eq!(crates_found.len(), 2, "Should find exactly 2 crates");
76 let mut paths = Vec::new();
77 for c in crates_found.iter() {
78 paths.push(c.lock().await.root_dir_path_buf());
79 }
80 assert!(paths.contains(&crate_a));
81 assert!(paths.contains(&crate_b));
82
83 info!("test_find_items_in_directory passed");
84 }
85
86 #[traced_test]
90 async fn test_find_items_in_empty_directory() {
91 let tmp = tempdir().unwrap();
92 let root = tmp.path().to_path_buf();
93
94 let crates_found = MyWorkspace::find_items(&root).await
95 .expect("Reading an empty dir should not error");
96 assert_eq!(crates_found.len(), 0, "No subdirs => no crates found");
97 }
98
99 #[traced_test]
104 async fn test_find_items_directory_not_found() {
105 let bad_path = PathBuf::from("/this/path/should/not/exist-12345");
106 let result = MyWorkspace::find_items(&bad_path).await;
107 assert!(result.is_err(), "Should fail on non-existent directory");
108
109 match result.err().unwrap() {
110 WorkspaceError::DirectoryError(DirectoryError::ReadDirError { .. }) => {
111 info!("Got expected DirectoryError::ReadDirError for missing directory");
112 }
113 other => {
114 panic!("Expected DirectoryError::ReadDirError, got: {:?}", other);
115 }
116 }
117 }
118}