- ReadDir
Iterator to walk directory tree
examples/iterators/walk-directory-tree-return-strings/src/main.rs
use std::fs::ReadDir; use std::path::Path; //#[derive(Debug)] //#[allow(dead_code)] struct Walk { rds: Vec<ReadDir>, } impl Walk { fn new(root: &str) -> Result<Walk, Box<dyn std::error::Error>> { let path = Path::new(root); match path.read_dir() { Ok(rd) => { let w = Walk { rds: vec![rd] }; std::result::Result::Ok(w) } Err(err) => { println!("Could not open dir '{}': {}", root, err); Err(Box::new(err)) } } } } impl Iterator for Walk { type Item = String; fn next(&mut self) -> Option<Self::Item> { if self.rds.is_empty() { //println!("empty rds"); return None; } let count = self.rds.len(); let entry = self.rds[count - 1].next(); match entry { Some(result) => match result { Ok(dir_entry) => { if dir_entry.path().is_dir() { match dir_entry.path().read_dir() { Ok(rd) => { self.rds.push(rd); } Err(err) => { println!("Could not open dir {}", err); } } } return Some(dir_entry.path().to_str().unwrap().to_string()); } Err(_err) => None, }, None => { self.rds.pop(); self.next() } } } } fn main() { let args: Vec<String> = std::env::args().collect(); if args.len() != 2 { eprintln!("Usage: {} PATH", args[0]); std::process::exit(1); } let path_from_user = &args[1]; let tree = match Walk::new(path_from_user) { Ok(tree) => tree, Err(err) => { println!("Error: {}", err); std::process::exit(1); } }; //println!("{:?}", &tree); for entry in tree { println!("{:?}", entry); } }