asimov_directory/fs/
module_iterators.rs1use asimov_core::ModuleName;
4use asimov_module::InstalledModuleManifest;
5use camino::Utf8PathBuf;
6use std::io::Result;
7use tokio::fs::ReadDir;
8
9#[derive(Debug)]
11pub struct ModuleNameIterator {
12 dir: ReadDir,
13}
14
15impl ModuleNameIterator {
16 pub async fn new(path: Utf8PathBuf) -> Result<Self> {
17 Ok(ModuleNameIterator {
18 dir: tokio::fs::read_dir(path).await?,
19 })
20 }
21}
22
23impl crate::ModuleNameIterator for ModuleNameIterator {
24 async fn next(&mut self) -> Option<ModuleName> {
25 while let Some(entry) = self.dir.next_entry().await.transpose() {
26 if let Ok(entry) = entry
27 && let Some(entry_name) = entry.file_name().to_str()
28 && !entry_name.starts_with(".")
29 && let Ok(entry_type) = entry.file_type().await
30 && (entry_type.is_dir() || entry_type.is_symlink())
31 && let Ok(module_name) = ModuleName::try_from(entry_name)
32 {
33 return Some(module_name);
34 }
35 }
36 None
37 }
38}
39
40#[derive(Debug)]
42pub struct ModuleManifestIterator {
43 dir: ReadDir,
44}
45
46impl ModuleManifestIterator {
47 pub async fn new(path: Utf8PathBuf) -> Result<Self> {
48 Ok(ModuleManifestIterator {
49 dir: tokio::fs::read_dir(path).await?,
50 })
51 }
52}
53
54impl crate::ModuleManifestIterator for ModuleManifestIterator {
55 async fn next(&mut self) -> Option<InstalledModuleManifest> {
56 while let Some(entry) = self.dir.next_entry().await.transpose() {
57 if let Ok(entry) = entry
58 && let Some(entry_name) = entry.file_name().to_str()
59 && !entry_name.starts_with(".")
60 && let Ok(entry_type) = entry.file_type().await
61 && (entry_type.is_dir() || entry_type.is_symlink())
62 && let Ok(content) = tokio::fs::read(entry.path().join("manifest.json")).await
63 && let Ok(manifest) = serde_json::from_slice(&content)
64 {
65 return Some(manifest);
66 }
67 }
68 None
69 }
70}