You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
68 lines
1.1 KiB
68 lines
1.1 KiB
use std::path::Path;
|
|
use std::fs::{ReadDir, DirEntry};
|
|
use std::vec::*;
|
|
use std::io;
|
|
|
|
pub struct DirectoryIterator<P>
|
|
{
|
|
root: P,
|
|
dirs: Vec<DirEntry>,
|
|
}
|
|
|
|
fn traverse<P>(path: P, out: &mut Vec<DirEntry>) -> io::Result<()>
|
|
where P:AsRef<Path>
|
|
{
|
|
for entry in std::fs::read_dir(path)? {
|
|
match entry {
|
|
Ok(entry) => out.push(entry),
|
|
Err(_) => (),
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
impl<P> DirectoryIterator<P>
|
|
where P: AsRef<Path>
|
|
{
|
|
pub fn begin(path: P) -> Result<Self, std::io::Error> {
|
|
|
|
let mut cache = Vec::new();
|
|
|
|
traverse(&path, &mut cache)?;
|
|
|
|
Ok(Self{
|
|
root: path,
|
|
dirs: cache,
|
|
})
|
|
}
|
|
|
|
}
|
|
|
|
impl<P: AsRef<Path>> Iterator for DirectoryIterator<P>
|
|
{
|
|
type Item = String;
|
|
|
|
fn next(&mut self) -> Option<Self::Item>
|
|
{
|
|
let current = self.dirs.pop();
|
|
|
|
if let Some(current) = current {
|
|
let path = current.path();
|
|
|
|
if path.is_dir() {
|
|
let _ = traverse(&path, &mut self.dirs);
|
|
self.next()
|
|
} else {
|
|
|
|
match path.as_path().to_str() {
|
|
Some(path) => Some(path.to_string()),
|
|
None => self.next(),
|
|
}
|
|
}
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
}
|