use crate::{get_path, Arguments, FileInfo, Key, MyResult};
use rayon::prelude::*;
use std::{ops::RangeInclusive, path::PathBuf, process};
use walkdir::{DirEntry, WalkDir};
pub fn get_all_files(arguments: &Arguments) -> MyResult<Vec<FileInfo>> {
let size_range: RangeInclusive<u64> = arguments.get_size_range();
let entries: Vec<DirEntry> = get_entries(arguments)?;
let all_files: Vec<FileInfo> = entries
.into_par_iter() .filter_map(|entry| {
if let Ok(metadata) = entry.metadata() {
let size_u64: u64 = metadata.len();
if size_range.contains(&size_u64) {
let key = Key::new(size_u64, None);
let path = entry.into_path();
Some(FileInfo { key, path })
} else {
None
}
} else {
None
}
})
.collect();
Ok(all_files)
}
fn get_entries(arguments: &Arguments) -> MyResult<Vec<DirEntry>> {
let path: PathBuf = get_path(arguments)?;
let min_depth: usize = arguments.min_depth.unwrap_or(0);
let max_depth: usize = arguments.max_depth.unwrap_or(std::usize::MAX);
let entries: Vec<DirEntry> = WalkDir::new(path)
.min_depth(min_depth)
.max_depth(max_depth)
.into_iter()
.filter_entry(|e| !arguments.omit_hidden || !is_hidden(e))
.map_while(|result| match result {
Ok(dir_entry) => Some(dir_entry),
Err(why) => {
eprintln!("Error: {why}");
process::exit(1)
}
})
.filter(|entry| entry.file_type().is_file())
.collect();
Ok(entries)
}
fn is_hidden(entry: &DirEntry) -> bool {
entry
.file_name()
.to_str()
.map(|s| entry.depth() != 0 && s.starts_with('.'))
.unwrap_or(false)
}