summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsharkdp <davidpeter@web.de>2018-11-04 20:35:45 +0100
committersharkdp <davidpeter@web.de>2018-11-04 20:35:45 +0100
commit85ba887a9ce56c94861cfc60cce6eae90b9f3a79 (patch)
treef46afeb9ff879af734e5248eb0a3e14fb5dc44e9
parentc9c8412dc829b3e60a1f6577c85d4c1363a5dfab (diff)
Move error handling to main thread
-rw-r--r--src/main.rs2
-rw-r--r--src/walk.rs51
2 files changed, 37 insertions, 16 deletions
diff --git a/src/main.rs b/src/main.rs
index 83b1027..1a17a51 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,9 +1,9 @@
#[macro_use]
extern crate clap;
+extern crate crossbeam_channel;
extern crate humansize;
extern crate num_cpus;
extern crate rayon;
-extern crate crossbeam_channel;
mod walk;
diff --git a/src/walk.rs b/src/walk.rs
index a5daac6..28a1059 100644
--- a/src/walk.rs
+++ b/src/walk.rs
@@ -8,12 +8,16 @@ use crossbeam_channel as channel;
use rayon::prelude::*;
-#[derive(Eq,PartialEq,Hash)]
+#[derive(Eq, PartialEq, Hash)]
struct UniqueID(u64, u64);
-struct SizeEntry(Option<UniqueID>, u64);
+enum Message {
+ SizeEntry(Option<UniqueID>, u64),
+ NoMetadataForPath(PathBuf),
+ CouldNotReadDir(PathBuf),
+}
-fn walk(tx: channel::Sender<SizeEntry>, entries: &[PathBuf]) {
+fn walk(tx: channel::Sender<Message>, entries: &[PathBuf]) {
entries.into_par_iter().for_each_with(tx, |tx_ref, entry| {
if let Ok(metadata) = entry.symlink_metadata() {
// If the entry has more than one hard link, generate
@@ -27,20 +31,27 @@ fn walk(tx: channel::Sender<SizeEntry>, entries: &[PathBuf]) {
let size = metadata.len();
- tx_ref.send(SizeEntry(unique_id, size)).unwrap();
+ tx_ref.send(Message::SizeEntry(unique_id, size)).unwrap();
if metadata.is_dir() {
let mut children = vec![];
- for child_entry in fs::read_dir(entry).unwrap() {
- if let Ok(child_entry) = child_entry {
- children.push(child_entry.path());
+ match fs::read_dir(entry) {
+ Ok(child_entries) => {
+ for child_entry in child_entries {
+ if let Ok(child_entry) = child_entry {
+ children.push(child_entry.path());
+ }
+ }
+ }
+ Err(err) => {
+ tx_ref.send(Message::CouldNotReadDir(entry.clone())).unwrap();
}
}
walk(tx_ref.clone(), &children[..]);
};
} else {
- eprintln!("Could not get file metadata: '{}'", entry.to_string_lossy());
+ tx_ref.send(Message::NoMetadataForPath(entry.clone())).unwrap();
};
});
}
@@ -64,14 +75,24 @@ impl<'a> Walk<'a> {
let receiver_thread = thread::spawn(move || {
let mut total = 0;
let mut ids = HashSet::new();
- for SizeEntry(unique_id, size) in rx {
- if let Some(unique_id) = unique_id {
- // Only count this entry if the ID has not been seen
- if ids.insert(unique_id) {
- total += size;
+ for msg in rx {
+ match msg {
+ Message::SizeEntry(unique_id, size) => {
+ if let Some(unique_id) = unique_id {
+ // Only count this entry if the ID has not been seen
+ if ids.insert(unique_id) {
+ total += size;
+ }
+ } else {
+ total += size;
+ }
+ }
+ Message::NoMetadataForPath(path) => {
+ eprintln!("diskus: could not metadata for path '{}'", path.to_string_lossy());
+ }
+ Message::CouldNotReadDir(path) => {
+ eprintln!("diskus: could not contents of directory '{}'", path.to_string_lossy());
}
- } else {
- total += size;
}
}