pawkit_fs/
list_files_recursive.rs1use crate::{Vfs, VfsError, VfsListDirectories, VfsListFiles};
2
3pub struct VfsListFilesRecursive {
4 pub(crate) stack: Vec<(Vfs, VfsListDirectories)>,
5 pub(crate) files: Option<VfsListFiles>,
6 pub(crate) prefix: Box<str>,
7}
8
9impl VfsListFilesRecursive {
10 fn next_file(&mut self) -> Option<<Self as Iterator>::Item> {
11 if let Some(files) = &mut self.files {
12 if let Some(file) = files.next() {
13 match file {
14 Ok(file) => {
15 let prefix = self
16 .stack
17 .last()
18 .map(|it| it.0.subdirectory.as_ref())
19 .unwrap_or(None)
20 .unwrap_or(&self.prefix);
21
22 let prefix = &prefix[self.prefix.len()..];
23
24 let prefix = prefix.strip_prefix("/").unwrap_or(prefix);
25
26 return Some(Ok(if prefix.is_empty() {
27 file
28 } else {
29 format!("{}/{}", prefix, file)
30 }));
31 }
32 Err(err) => return Some(Err(err)),
33 }
34 }
35 }
36
37 return None;
38 }
39
40 fn next_dir(&mut self) -> Option<<Self as Iterator>::Item> {
41 while let Some((vfs, dirs)) = self.stack.last_mut() {
42 match dirs.next() {
43 Some(Ok(dir)) => {
44 let new_vfs = match vfs.subdirectory(&dir) {
45 Ok(value) => value,
46 Err(err) => return Some(Err(err)),
47 };
48
49 let new_dirs = match new_vfs.list_subdirectories() {
50 Ok(value) => value,
51 Err(err) => return Some(Err(err)),
52 };
53
54 let new_files = match new_vfs.list_files() {
55 Ok(value) => value,
56 Err(err) => return Some(Err(err)),
57 };
58
59 self.stack.push((new_vfs, new_dirs));
60 self.files = Some(new_files);
61 break;
62 }
63
64 Some(Err(err)) => return Some(Err(err)),
65
66 None => {
67 self.stack.pop();
68 }
69 }
70 }
71
72 return None;
73 }
74}
75
76impl Iterator for VfsListFilesRecursive {
77 type Item = Result<String, VfsError>;
78
79 fn next(&mut self) -> Option<Self::Item> {
80 while !self.stack.is_empty() {
81 if let Some(value) = self.next_file() {
82 return Some(value);
83 }
84
85 if let Some(value) = self.next_dir() {
86 return Some(value);
87 }
88 }
89
90 return None;
91 }
92}