//! Print the SHA256 sum of each regular file in the current directory recursively. use std::{fs::File, path::PathBuf}; use parseq::ParallelIterator; use sha2::{Digest, Sha256}; use walkdir::WalkDir; fn main() { WalkDir::new(".") .sort_by_file_name() .into_iter() .filter_map(|entry| match entry { Ok(entry) if entry.file_type().is_file() => Some(Ok(entry.into_path())), Ok(_) => None, Err(err) => Some(Err(Error::WalkdirError(err))), }) .map_parallel(|item| { item.and_then(|path| { let mut file = File::open(&path).map_err(|err| Error::IoError(path.clone(), err))?; let mut hasher = Sha256::new(); std::io::copy(&mut file, &mut hasher) .map_err(|err| Error::IoError(path.clone(), err))?; Ok((path, hasher.finalize())) }) }) .for_each(|item| match item { Ok((path, hash)) => println!("{:x} {}", hash, path.display()), Err(err) => eprintln!("{err}"), }); } #[derive(Debug)] enum Error { WalkdirError(walkdir::Error), IoError(PathBuf, std::io::Error), } impl std::error::Error for Error {} impl std::fmt::Display for Error { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Error::WalkdirError(err) => { if let Some(path) = err.path() { write!(f, "{}: {}", path.display(), err) } else { write!(f, "{err}") } } Error::IoError(path, err) => write!(f, "{}: {}", path.display(), err), } } }