wordcloud/io/
folder.rs

1use std::fs::{canonicalize, read_dir};
2use std::io::Error;
3use std::iter::FusedIterator;
4use std::path::{Path, PathBuf};
5
6/**
7Recursively iterates through items in the given folder, which match the given filter
8 */
9pub struct RecursiveFolderIterator {
10    folder: Vec<PathBuf>,
11    file: Vec<PathBuf>,
12    filter_fn: fn(&Path) -> bool,
13}
14
15impl RecursiveFolderIterator {
16    pub fn new(folder: &Path, filter: fn(&Path) -> bool) -> Result<Self, Error> {
17        Ok(RecursiveFolderIterator {
18            folder: vec![folder.canonicalize()?],
19            file: Vec::new(),
20            filter_fn: filter,
21        })
22    }
23}
24
25impl Iterator for RecursiveFolderIterator {
26    type Item = PathBuf;
27
28    fn next(&mut self) -> Option<Self::Item> {
29        loop {
30            while let Some(file) = self.file.pop() {
31                if (self.filter_fn)(file.as_path()) {
32                    return Some(file);
33                }
34            }
35
36            if let Some(folder) = self.folder.pop() {
37                if let Ok(fl) = read_dir(folder) {
38                    for f in fl.flatten() {
39                        let pth = match canonicalize(f.path()) {
40                            Ok(x) => x,
41                            Err(_) => continue,
42                        };
43                        if pth.is_dir() {
44                            self.folder.push(pth);
45                        } else if pth.is_file() {
46                            self.file.push(pth);
47                        }
48                    }
49                };
50            } else {
51                break;
52            }
53        }
54
55        None
56    }
57}
58
59impl FusedIterator for RecursiveFolderIterator {}