fast_walker/dir_walker/sync_iter/
mod.rs

1use super::*;
2
3impl<'i> IntoIterator for &'i WalkPlan {
4    type Item = Result<WalkItem, WalkError>;
5    type IntoIter = LinearWalker<'i>;
6
7    fn into_iter(self) -> Self::IntoIter {
8        LinearWalker {
9            config: &self,
10            tasks: self.check_list.iter().map(|s| WalkItem::from(s.as_path())).collect(),
11            results: vec![],
12            found_files: 0,
13        }
14    }
15}
16
17pub struct LinearWalker<'i> {
18    config: &'i WalkPlan,
19    tasks: VecDeque<WalkItem>,
20    results: Vec<Result<WalkItem, WalkError>>,
21    found_files: usize,
22}
23
24impl<'i> LinearWalker<'i> {
25    fn pop(&mut self) -> Option<WalkItem> {
26        if self.config.depth_first { self.tasks.pop_back() } else { self.tasks.pop_front() }
27    }
28    fn read_item(&mut self, entry: WalkItem) {
29        if (self.config.finish_when)(&entry) {
30            self.tasks.clear();
31            self.results.push(Ok(entry));
32            return;
33        }
34        if entry.path.is_symlink() {
35            self.read_link(entry);
36            return;
37        }
38        if entry.is_directory() {
39            self.read_directory(entry);
40            return;
41        }
42        self.read_file(entry)
43    }
44    fn read_link(&mut self, entry: WalkItem) {
45        if self.config.follow_symlinks {
46            match entry.read_link() {
47                Ok(o) => {
48                    self.tasks.push_back(WalkItem::from(o).with_depth(entry.depth + 1));
49                }
50                Err(e) => {
51                    self.results.push(Err(WalkError::io_error(entry.path, e)));
52                }
53            }
54        }
55    }
56    fn read_directory(&mut self, entry: WalkItem) {
57        if (self.config.ignore_when)(&entry) {
58            return;
59        }
60        match entry.read_directory() {
61            Ok(dir) => {
62                for result in dir {
63                    match result {
64                        Ok(child) => {
65                            self.tasks.push_back(WalkItem::from(child).with_depth(entry.depth + 1));
66                        }
67                        Err(e) => {
68                            self.results.push(Err(WalkError::io_error(entry.path.clone(), e)));
69                            continue;
70                        }
71                    }
72                }
73            }
74            Err(e) => {
75                self.results.push(Err(WalkError::io_error(entry.path, e)));
76            }
77        }
78    }
79    fn read_file(&mut self, entry: WalkItem) {
80        debug_assert!(entry.is_file());
81        if (self.config.reject_when)(&entry) {
82            return;
83        }
84        self.found_files += 1;
85        self.results.push(Ok(entry));
86    }
87}
88
89impl<'i> Iterator for LinearWalker<'i> {
90    type Item = Result<WalkItem, WalkError>;
91
92    fn next(&mut self) -> Option<Self::Item> {
93        match self.results.pop() {
94            Some(s) => {
95                return Some(s);
96            }
97            None => match self.pop() {
98                Some(s) => {
99                    self.read_item(s);
100                    self.next()
101                }
102                None => None,
103            },
104        }
105    }
106}
107
108#[test]
109fn run() {
110    let plan = WalkPlan {
111        check_list: vec![
112            PathBuf::from(r#"C:\Users\Dell\CLionProjects\fast-walker"#),
113            PathBuf::from(r#"C:\Users\Dell\CLionProjects\faster-pest"#),
114        ],
115        follow_symlinks: true,
116        depth_first: true,
117        capacity: 4,
118        threads: 4,
119        reject_when: |_| false,
120        ignore_when: |_| false,
121        finish_when: |_| false,
122    };
123
124    for item in plan.into_iter().take(10) {
125        match item {
126            Ok(o) => {
127                println!("File: {:?}", o);
128            }
129            Err(e) => {
130                println!("Error: {:?}", e);
131            }
132        }
133    }
134}