use futures::future::BoxFuture;
use std::fs;
use std::io;
use std::path::PathBuf;
pub fn get_file_paths<'a>(
dir_path: &'a str,
include: Option<Vec<&'a str>>,
exclude: Option<Vec<&'a str>>,
) -> BoxFuture<'a, io::Result<Vec<PathBuf>>> {
Box::pin(async move {
let mut entries: Vec<PathBuf> = Vec::new();
let dir = fs::read_dir(dir_path)?;
for entry in dir {
let entry = entry?;
let path = entry.path();
let path_str = path.to_str().unwrap_or_default();
if let Some(ref include) = include {
if !include.is_empty() && !include.iter().any(|inc| path_str.contains(inc)) {
continue;
}
}
if let Some(ref exclude) = exclude {
if !exclude.is_empty() && exclude.iter().any(|exc| path_str.contains(exc)) {
continue;
}
}
if path.is_dir() {
let sub_entries =
get_file_paths(path.to_str().unwrap(), include.clone(), exclude.clone())
.await?;
entries.extend(sub_entries);
} else {
entries.push(path);
}
}
Ok(entries)
})
}
#[cfg(test)]
mod tests {
use super::*;
use std::fs::{self, File};
#[tokio::test]
async fn test_get_file_paths() {
let temp_dir = tempfile::tempdir().unwrap();
let temp_dir_path = temp_dir.path();
let sub_dir = temp_dir_path.join("subdir");
fs::create_dir(&sub_dir).unwrap();
let file1 = temp_dir_path.join("file1.jpg");
let file2 = sub_dir.join("file2.png");
File::create(&file1).unwrap();
File::create(&file2).unwrap();
let file_paths = get_file_paths(temp_dir_path.to_str().unwrap(), None, None)
.await
.unwrap();
assert_eq!(file_paths.len(), 2);
assert!(file_paths.contains(&file1));
assert!(file_paths.contains(&file2));
let include_filter = vec!["file1"];
let file_paths =
get_file_paths(temp_dir_path.to_str().unwrap(), Some(include_filter), None)
.await
.unwrap();
assert_eq!(file_paths.len(), 1);
assert!(file_paths.contains(&file1));
assert!(!file_paths.contains(&file2));
let exclude_filter = vec!["file1"];
let file_paths =
get_file_paths(temp_dir_path.to_str().unwrap(), None, Some(exclude_filter))
.await
.unwrap();
assert_eq!(file_paths.len(), 1);
assert!(!file_paths.contains(&file1));
assert!(file_paths.contains(&file2));
}
}