implement file traversal (without recursion)

This commit is contained in:
mykola2312 2024-03-17 23:18:14 +02:00
parent cea58a53c3
commit 607a1b90f2

View file

@ -1,7 +1,8 @@
use clap::Parser;
use std::fs;
use std::fs::{self, DirEntry, FileType, ReadDir};
use std::collections::HashMap;
use std::num::ParseIntError;
use std::path::Path;
#[derive(Parser, Debug)]
#[command(version, about)]
@ -64,6 +65,62 @@ const GROUP_PATH: &str = "group";
#[cfg(not(debug_assertions))]
const GROUP_PATH: &str = "/etc/group";
fn traverse_filesystem(path: &Path) -> (Vec<String>, Vec<String>){
let mut files: Vec<String> = Vec::new();
let mut directories: Vec<String> = Vec::new();
let entries: Vec<DirEntry> = fs::read_dir(path)
.unwrap()
.filter_map(|f| f.ok())
.collect();
let mut entry_list: Vec<Vec<DirEntry>> = vec!{entries};
loop {
let drained: Vec<Vec<DirEntry>> = entry_list.drain(..).collect();
for entries in drained {
for entry in entries {
let path = match entry.path().canonicalize() {
Ok(path) => match path.to_str() {
Some(path) => path.to_owned(),
None => {
eprintln!("failed to convert {:?} into a string", path);
continue
}
},
Err(e) => {
eprintln!("failed to get absolute path: {e}");
continue;
}
};
let file_type = match entry.file_type() {
Ok(file_type) => file_type,
Err(e) => {
eprintln!("error {} getting file type for {}", e, path);
continue;
}
};
if file_type.is_file() {
files.push(path);
} else if file_type.is_dir() {
let entries: Vec<DirEntry> = fs::read_dir(&path)
.unwrap()
.filter_map(|f| f.ok())
.collect();
entry_list.push(entries);
directories.push(path);
}
}
}
if entry_list.is_empty() {
break;
}
}
(files, directories)
}
fn main() {
let args = Args::parse();
@ -75,5 +132,5 @@ fn main() {
let uid = users.get(&args.user).expect("user not found");
let gid = groups.get(&args.group).expect("group not found");
dbg!(uid, gid);
dbg!(traverse_filesystem(Path::new(&args.path)));
}