diff options
Diffstat (limited to 'src/main.rs')
-rw-r--r-- | src/main.rs | 125 |
1 files changed, 11 insertions, 114 deletions
diff --git a/src/main.rs b/src/main.rs index 9dfa59c..c31dd20 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,10 @@ use std::env; -use std::path::PathBuf; use std::io; -use std::cmp::Ordering; +use std::fs; +use std::os::unix::fs::PermissionsExt; + +mod fswalk; +use fswalk::DirTree; // Command line args are names of dirs, recursively list all files and // dirs them @@ -9,125 +12,19 @@ fn main() -> io::Result<()> { for dirname in env::args().skip(1) { let tree = DirTree::new(&dirname); for entry in tree { - println!("{}", entry.path()); + write_info(&entry.path(), &entry.metadata()); } } Ok(()) } -// A filesystem entry: directory, file, symlink, etc -#[derive(Debug)] -struct Entry { - path: PathBuf, -} - -impl Entry { - fn new(path: &PathBuf) -> Entry { - Entry { - path: path.clone(), - } - } - - fn path(&self) -> String { - self.path.to_string_lossy().to_string() - } -} - -impl Eq for Entry {} - -impl PartialEq for Entry { - fn eq(&self, other: &Entry) -> bool { - self.path == other.path - } -} - -impl Ord for Entry { - fn cmp(&self, other: &Entry) -> Ordering { - self.path.cmp(&other.path) - } -} - -impl PartialOrd for Entry { - fn partial_cmp(&self, other: &Entry) -> Option<Ordering> { - Some(self.path.cmp(&other.path)) - } -} - - -// Keep two stacks of Entry values, sorted in ascending order. The -// first stack has non-directories. When we iterate, we return a -// directory, then of its non-dirs, then recurse each of its subdirs. -#[derive(Debug)] -struct DirTree { - entries: Vec<Entry>, - dirs: Vec<Entry>, +fn write_info(path: &str, meta: &fs::Metadata) { + println!("{} {}", format_metadata(&meta), path); } -impl DirTree { - fn empty() -> DirTree { - DirTree { - entries: Vec::new(), - dirs: Vec::new(), - } - } - - fn new(path: &str) -> DirTree { - let mut dt = DirTree::empty(); - dt.add_dir(&PathBuf::from(path)); - dt - } - - fn add_dir(&mut self, path: &PathBuf) { - let entry = Entry::new(path); - self.dirs.push(entry); - } - - fn add_entries(&mut self, path: &PathBuf) -> io::Result<()> { - let mut entries = Vec::new(); - let mut dirs = Vec::new(); - for dir_entry in path.read_dir()? { - let dir_entry = dir_entry?; - let metadata = dir_entry.metadata()?; - let entry = Entry::new(&dir_entry.path()); - if metadata.is_dir() { - dirs.push(entry); - } else { - entries.push(entry); - } - } - - entries.sort(); - entries.reverse(); - for e in entries { - self.entries.push(e); - } - - dirs.sort(); - dirs.reverse(); - for e in dirs { - self.dirs.push(e); - } - - Ok(()) - } -} - -impl Iterator for DirTree { - type Item = Entry; - - fn next(&mut self) -> Option<Entry> { - if let Some(e) = self.entries.pop() { - Some(e) - } else if let Some(e) = self.dirs.pop() { - if let Ok(_) = self.add_entries(&e.path) { - // We ignore any errors from adding entries. Boo. Not - // sure how I'd propagate errors, from a next method. - } - Some(e) - } else { - None - } - } +fn format_metadata(meta: &fs::Metadata) -> String { + let mode = meta.permissions().mode(); + format!("{:06o}", mode) } |