1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
use std::iter::Peekable;
use std::sync::Arc;
use super::*;
pub enum ReadDirIter {
Walk {
read_dir_spec_stack: Vec<Ordered<Arc<ReadDirSpec>>>,
client_function: Arc<ClientReadDirFunction>,
},
ParWalk {
read_dir_result_iter: OrderedQueueIter<Result<ReadDir>>,
},
}
impl Iterator for ReadDirIter {
type Item = Result<ReadDir>;
fn next(&mut self) -> Option<Self::Item> {
match self {
ReadDirIter::Walk {
read_dir_spec_stack,
client_function,
} => {
let read_dir_spec = read_dir_spec_stack.pop()?;
let (read_dir_result, content_specs) = run_client_function(client_function, read_dir_spec);
if let Some(content_specs) = content_specs {
for each in content_specs.into_iter().rev() {
read_dir_spec_stack.push(each)
}
}
Some(read_dir_result.value)
}
ReadDirIter::ParWalk {
read_dir_result_iter,
} => read_dir_result_iter
.next()
.and_then(|read_dir_result| Some(read_dir_result.value)),
}
}
}
pub struct DirEntryIter {
read_dir_iter_stack: Vec<vec::IntoIter<Result<DirEntry>>>,
read_dir_iter: Peekable<ReadDirIter>,
root_entry_result: Option<Result<DirEntry>>,
}
impl DirEntryIter {
pub(crate) fn new(
read_dir_iter: ReadDirIter,
root_entry_result: Result<DirEntry>,
) -> DirEntryIter {
DirEntryIter {
read_dir_iter: read_dir_iter.peekable(),
read_dir_iter_stack: Vec::new(),
root_entry_result: Some(root_entry_result),
}
}
fn push_next_read_dir_iter(&mut self) -> Option<Error> {
let read_dir_result = self.read_dir_iter.next().unwrap();
let read_dir = match read_dir_result {
Ok(read_dir) => read_dir,
Err(err) => return Some(err),
};
self.read_dir_iter_stack.push(read_dir.into_iter());
None
}
}
impl Iterator for DirEntryIter {
type Item = Result<DirEntry>;
fn next(&mut self) -> Option<Self::Item> {
if let Some(root_entry_result) = self.root_entry_result.take() {
return Some(root_entry_result);
}
loop {
if self.read_dir_iter_stack.is_empty() {
if self.read_dir_iter.peek().is_some() {
self.push_next_read_dir_iter();
} else {
return None;
}
}
let top_read_dir_iter = self.read_dir_iter_stack.last_mut().unwrap();
if let Some(dir_entry_result) = top_read_dir_iter.next() {
let mut dir_entry = match dir_entry_result {
Ok(dir_entry) => dir_entry,
Err(err) => return Some(Err(err)),
};
if dir_entry.content_spec.is_some() {
dir_entry.content_error = self.push_next_read_dir_iter();
}
return Some(Ok(dir_entry));
} else {
self.read_dir_iter_stack.pop();
}
}
}
}