1#![forbid(unsafe_code, rust_2018_idioms)]
4#![deny(missing_debug_implementations, nonstandard_style)]
5#![warn(missing_docs, future_incompatible, unreachable_pub)]
6
7use std::fs::{self, DirEntry, ReadDir};
8use std::io;
9use std::path::Path;
10
11pub fn read_dir_all<P: AsRef<Path>>(path: P) -> io::Result<ReadDirAll> {
13 let reader = fs::read_dir(path)?;
14 Ok(ReadDirAll {
15 readers: vec![reader],
16 })
17}
18
19#[derive(Debug)]
24pub struct ReadDirAll {
25 readers: Vec<ReadDir>,
26}
27
28impl ReadDirAll {
29 fn visit_dir(&mut self, entry: DirEntry) -> Result<DirEntry, io::Error> {
31 let reader = fs::read_dir(entry.path())?;
33 self.readers.push(reader);
34
35 Ok(entry)
37 }
38}
39
40impl Iterator for ReadDirAll {
41 type Item = io::Result<DirEntry>;
42
43 fn next(&mut self) -> Option<Self::Item> {
44 loop {
45 let reader = self.readers.last_mut()?;
48
49 match reader.next() {
50 None => self.readers.pop(),
52
53 Some(Ok(entry)) if entry.path().is_dir() => return Some(self.visit_dir(entry)),
55
56 result => return result,
58 };
59 }
60 }
61}