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
// Copyright 2021 System76 <info@system76.com>
// SPDX-License-Identifier: MPL-2.0
use std::{fs, path::PathBuf};
pub struct Iter {
directories_to_walk: Vec<PathBuf>,
actively_walking: Option<fs::ReadDir>,
}
impl Iter {
/// Directories will be processed in order, starting from the end.
pub fn new(directories_to_walk: Vec<PathBuf>) -> Self {
Self {
directories_to_walk,
actively_walking: None,
}
}
}
impl Iterator for Iter {
type Item = PathBuf;
fn next(&mut self) -> Option<Self::Item> {
'outer: loop {
let mut iterator = match self.actively_walking.take() {
Some(dir) => dir,
None => {
while let Some(path) = self.directories_to_walk.pop() {
match fs::read_dir(&path) {
Ok(directory) => {
self.actively_walking = Some(directory);
continue 'outer;
}
// Skip directories_to_walk which could not be read
Err(_) => continue,
}
}
return None;
}
};
while let Some(entry) = iterator.next() {
if let Ok(entry) = entry {
let path = entry.path();
if let Ok(file_type) = entry.file_type() {
if file_type.is_dir() {
self.directories_to_walk.push(path);
} else if (file_type.is_file() || file_type.is_symlink())
&& path.extension().map_or(false, |ext| ext == "desktop")
{
self.actively_walking = Some(iterator);
return Some(path);
}
}
}
}
}
}
}