summaryrefslogtreecommitdiff
path: root/src/main.rs
blob: 109a6b3134c67ba025220513b5e1420ced65770f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
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, String>;


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<DirEntry> = vec![];
    let entries = WalkDir::new(dirname)
        .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<Map> = 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: BTreeMap<&str, String> =
        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());
}