hel_fs/read/
read_dir_rec.rs1use std::{
2 fs::{self, ReadDir},
3 io,
4 path::Path,
5};
6
7#[derive(Debug)]
8pub struct ReadDirRec(Vec<ReadDir>);
9
10pub fn read_dir_rec<P: AsRef<Path>>(path: P) -> io::Result<ReadDirRec> {
12 Ok(fs::read_dir(path)?.into())
13}
14
15impl From<ReadDir> for ReadDirRec {
16 fn from(value: std::fs::ReadDir) -> Self {
17 const CAP: usize = 5;
18 let mut inner = Vec::with_capacity(CAP);
19 inner.push(value);
20 Self(inner)
21 }
22}
23
24impl Iterator for ReadDirRec {
25 type Item = fs::DirEntry;
26
27 fn next(&mut self) -> Option<Self::Item> {
28 let last = self.0.last_mut()?;
29
30 let Some(Ok(entry)) = last.next() else {
31 self.0.pop();
32 return <Self as Iterator>::next(self)
33 };
34
35 let Ok(file_type) = entry.file_type() else {
36 return <Self as Iterator>::next(self)
37 };
38
39 if !file_type.is_dir() {
40 return Some(entry);
41 };
42
43 let Ok(dir) = fs::read_dir(entry.path()) else {
44 return <Self as Iterator>::next(self);
45 };
46
47 self.0.push(dir);
48
49 <Self as Iterator>::next(self)
50 }
51}
52
53#[cfg(test)]
54mod tests {
55 #[test]
56 fn read_dir() {
57 let contents: Vec<_> = crate::read_dir_rec(".").unwrap().collect();
58
59 assert!(!contents.is_empty());
60
61 assert!(
62 contents
63 .iter()
64 .filter(|entry| entry.file_name().to_str().unwrap().ends_with(".rs"))
65 .count() > 0
66 );
67 }
68}