exemplify_lib/layers/implementations/
fs_discovery.rs

1use std::path::Path;
2use std::pin::Pin;
3
4use futures::{Stream};
5
6pub fn discover_fs_files(root_folder: String, file_patterns: &Vec<String>) -> Result<Pin<Box<dyn Stream<Item=Result<String, String>>>>, String> {
7    let path = Path::new(root_folder.as_str());
8    let files = recursively_find_files(path, file_patterns)?;
9
10    Ok(Box::pin(futures::stream::iter(files.into_iter().map(|f| Ok(f)))))
11}
12
13fn recursively_find_files(root_folder: &Path, file_patterns: &Vec<String>) -> Result<Vec<String>, String> {
14    let mut files: Vec<String> = Vec::new();
15
16    for entry in std::fs::read_dir(root_folder).map_err(|e| e.to_string())? {
17        let entry = entry.map_err(|e| e.to_string())?;
18
19        let path = entry.path();
20
21        let metadata = std::fs::symlink_metadata(&path).map_err(|e| e.to_string())?;
22
23        if metadata.file_type().is_symlink() {
24            continue;
25        }
26
27        if path.is_file() {
28            for ext in file_patterns {
29                let string_path = path.to_str().ok_or("".to_string())?.to_string();
30
31                if path.extension().ok_or("Invalid filename")?.to_str().ok_or("Invalid filename")? == ext {
32                    files.push(string_path)
33                }
34            }
35        } else if path.is_dir() {
36            let mut sub_folder_files = recursively_find_files(&entry.path(), file_patterns)?;
37
38            files.append(&mut sub_folder_files);
39        }
40    }
41
42    Ok(files)
43}