Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 69 additions & 44 deletions src/dir_walker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,55 +126,80 @@ fn ignore_file(entry: &DirEntry, walk_data: &WalkData) -> bool {

fn walk(dir: PathBuf, walk_data: &WalkData, depth: usize) -> Option<Node> {
let prog_data = &walk_data.progress_data;
let mut children = vec![];

if let Ok(entries) = fs::read_dir(&dir) {
children = entries
.into_iter()
.par_bridge()
.filter_map(|entry| {
if let Ok(ref entry) = entry {
// uncommenting the below line gives simpler code but
// rayon doesn't parallelize as well giving a 3X performance drop
// hence we unravel the recursion a bit

// return walk(entry.path(), walk_data, depth)

if !ignore_file(entry, walk_data) {
if let Ok(data) = entry.file_type() {
if data.is_dir() || (walk_data.follow_links && data.is_symlink()) {
return walk(entry.path(), walk_data, depth + 1);
}

let node = build_node(
entry.path(),
vec![],
walk_data.filter_regex,
walk_data.invert_filter_regex,
walk_data.use_apparent_size,
data.is_symlink(),
data.is_file(),
walk_data.by_filecount,
depth,
);

prog_data.num_files.fetch_add(1, ORDERING);
if let Some(ref file) = node {
prog_data.total_file_size.fetch_add(file.size, ORDERING);
let children = if dir.is_dir() {
let read_dir = fs::read_dir(&dir);
match read_dir {
Ok(entries) => {
entries
.into_iter()
.par_bridge()
.filter_map(|entry| {
if let Ok(ref entry) = entry {
// uncommenting the below line gives simpler code but
// rayon doesn't parallelize as well giving a 3X performance drop
// hence we unravel the recursion a bit

// return walk(entry.path(), walk_data, depth)

if !ignore_file(entry, walk_data) {
if let Ok(data) = entry.file_type() {
if data.is_dir()
|| (walk_data.follow_links && data.is_symlink())
{
return walk(entry.path(), walk_data, depth + 1);
}

let node = build_node(
entry.path(),
vec![],
walk_data.filter_regex,
walk_data.invert_filter_regex,
walk_data.use_apparent_size,
data.is_symlink(),
data.is_file(),
walk_data.by_filecount,
depth,
);

prog_data.num_files.fetch_add(1, ORDERING);
if let Some(ref file) = node {
prog_data.total_file_size.fetch_add(file.size, ORDERING);
}

return node;
}
}

return node;
} else {
prog_data.no_permissions.store(true, ORDERING)
}
None
})
.collect()
}
Err(failed) => {
match failed.kind() {
std::io::ErrorKind::PermissionDenied => {
prog_data.no_permissions.store(true, ORDERING)
}
std::io::ErrorKind::NotFound => {
// TODO: consider turning this in to a array of the files that were not found
prog_data.no_file.store(true, ORDERING)
}
_ => {
println!("{:?}", failed);
prog_data.unknown_error.store(true, ORDERING)
}
} else {
prog_data.no_permissions.store(true, ORDERING)
}
None
})
.collect();
} else if !dir.is_file() {
walk_data.progress_data.no_permissions.store(true, ORDERING)
}
vec![]
}
}
} else {
if !dir.is_file() {
prog_data.no_file.store(true, ORDERING)
}
vec![]
};
build_node(
dir,
children,
Expand Down
8 changes: 8 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,11 +217,19 @@ fn main() {
};

let failed_permissions = indicator.data.no_permissions.load(ORDERING);
let no_file = indicator.data.no_file.load(ORDERING);
let unknown_error = indicator.data.unknown_error.load(ORDERING);
indicator.stop();
// Must have stopped indicator before we print to stderr
if no_file {
eprintln!("No such file or directory");
}
if failed_permissions {
eprintln!("Did not have permissions for all directories");
}
if unknown_error {
eprintln!("Unknown Error reading files");
}

if let Some(root_node) = tree {
let idd = InitialDisplayData {
Expand Down
2 changes: 2 additions & 0 deletions src/progress.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ pub struct PAtomicInfo {
pub state: AtomicU8,
pub current_path: ThreadStringWrapper,
pub no_permissions: AtomicBool,
pub no_file: AtomicBool,
pub unknown_error: AtomicBool,
}

impl PAtomicInfo {
Expand Down
2 changes: 1 addition & 1 deletion tests/test_flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ pub fn test_with_bad_param() {
let mut cmd = Command::cargo_bin("dust").unwrap();
let result = cmd.arg("bad_place").unwrap();
let stderr = str::from_utf8(&result.stderr).unwrap();
assert!(stderr.contains("Did not have permissions for all directories"));
assert!(stderr.contains("No such file or directory"));
}

#[test]
Expand Down