use std::{
collections::VecDeque,
path::{Path, PathBuf},
};
use blake3::{Hash, Hasher};
pub fn hash_file(path: impl AsRef<Path>) -> std::io::Result<Hash> {
let mut hasher = Hasher::new();
hasher.update_mmap(path)?;
Ok(hasher.finalize())
}
pub fn recurse_list_from_root<P: AsRef<Path>>(
root: P,
yield_dirs: bool,
) -> impl Iterator<Item = PathBuf> {
let mut stack = VecDeque::new();
stack.push_back(root.as_ref().to_owned());
std::iter::from_fn(move || {
while let Some(path) = stack.pop_back() {
if path.is_dir() {
if let Ok(entries) = path.read_dir() {
let filtered = entries.filter_map(Result::ok).map(|a| a.path());
stack.extend(filtered);
}
if yield_dirs {
return Some(path);
}
} else if path.is_file() {
return Some(path);
}
}
None
})
}
pub fn recurse_list_dirs<P: AsRef<Path>>(root: P) -> impl Iterator<Item = PathBuf> {
let mut stack = VecDeque::new();
stack.push_back(root.as_ref().to_owned());
std::iter::from_fn(move || {
while let Some(path) = stack.pop_back() {
if path.is_dir() {
if let Ok(entries) = path.read_dir() {
let filtered = entries.filter_map(Result::ok).map(|a| a.path());
stack.extend(filtered);
}
return Some(path);
}
}
None
})
}