1extern crate crossbeam_channel as channel;
2extern crate ignore;
3extern crate walkdir;
4
5use std::env;
6use std::io::{self, Write};
7use std::path::Path;
8use std::thread;
9
10use ignore::WalkBuilder;
11use walkdir::WalkDir;
12
13fn main() {
14 let mut path = env::args().nth(1).unwrap();
15 let mut parallel = false;
16 let mut simple = false;
17 let (tx, rx) = channel::bounded::<DirEntry>(100);
18 if path == "parallel" {
19 path = env::args().nth(2).unwrap();
20 parallel = true;
21 } else if path == "walkdir" {
22 path = env::args().nth(2).unwrap();
23 simple = true;
24 }
25
26 let stdout_thread = thread::spawn(move || {
27 let mut stdout = io::BufWriter::new(io::stdout());
28 for dent in rx {
29 write_path(&mut stdout, dent.path());
30 }
31 });
32
33 if parallel {
34 let walker = WalkBuilder::new(path).threads(6).build_parallel();
35 walker.run(|| {
36 let tx = tx.clone();
37 Box::new(move |result| {
38 use ignore::WalkState::*;
39
40 tx.send(DirEntry::Y(result.unwrap())).unwrap();
41 Continue
42 })
43 });
44 } else if simple {
45 let walker = WalkDir::new(path);
46 for result in walker {
47 tx.send(DirEntry::X(result.unwrap())).unwrap();
48 }
49 } else {
50 let walker = WalkBuilder::new(path).build();
51 for result in walker {
52 tx.send(DirEntry::Y(result.unwrap())).unwrap();
53 }
54 }
55 drop(tx);
56 stdout_thread.join().unwrap();
57}
58
59enum DirEntry {
60 X(walkdir::DirEntry),
61 Y(ignore::DirEntry),
62}
63
64impl DirEntry {
65 fn path(&self) -> &Path {
66 match *self {
67 DirEntry::X(ref x) => x.path(),
68 DirEntry::Y(ref y) => y.path(),
69 }
70 }
71}
72
73#[cfg(unix)]
74fn write_path<W: Write>(mut wtr: W, path: &Path) {
75 use std::os::unix::ffi::OsStrExt;
76 wtr.write(path.as_os_str().as_bytes()).unwrap();
77 wtr.write(b"\n").unwrap();
78}
79
80#[cfg(not(unix))]
81fn write_path<W: Write>(mut wtr: W, path: &Path) {
82 wtr.write(path.to_string_lossy().as_bytes()).unwrap();
83 wtr.write(b"\n").unwrap();
84}