extern crate chrono; extern crate crypto_hash; extern crate serde_yaml; extern crate walkdir; extern crate rayon; extern crate num_cpus; use std::env; use std::io; use std::collections::BTreeMap; use walkdir::{WalkDir, DirEntry}; use rayon::prelude::*; mod format; type Map = BTreeMap<&'static str, serde_yaml::Value>; fn main() -> io::Result<()> { let nproc = num_cpus::get(); for dirname in env::args().skip(1) { summain(&dirname, nproc); } Ok(()) } fn summain(dirname: &str, nproc: usize) { let mut chunk: Vec = vec![]; let entries = WalkDir::new(dirname) .sort_by(|a,b| a.file_name().cmp(b.file_name())) .into_iter() .filter_map(|e| e.ok()); for entry in entries { chunk.push(entry); if chunk.len() == nproc { process_chunk(&chunk); chunk.clear(); } } if chunk.len() > 0 { process_chunk(&chunk); } } fn process_chunk(chunk: &[DirEntry]) { let chunk: Vec = chunk.into_par_iter().map(mkmap).collect(); for map in chunk { print_map(map); } } fn mkmap(e: &DirEntry) -> Map { let fields = vec![ ("Name", format::name(&e)), ("Mtime", format::mtime(&e)), ("Mode", format::mode(&e)), ("Ino", format::inode(&e)), ("Dev", format::dev(&e)), ("Nlink", format::nlink(&e)), ("Size", format::size(&e)), ("Uid", format::uid(&e)), ("Username", format::username(&e)), ("Gid", format::gid(&e)), ("Group", format::group(&e)), ]; let mut map: Map = BTreeMap::from(fields.iter().cloned().collect()); if let Ok(m) = e.metadata() { if m.is_file() { map.insert("SHA256", format::sha256(&e)); } } map } fn print_map(map: Map) { println!("{}", serde_yaml::to_string(&map).unwrap()); }