use std::path::{Path, PathBuf}; use walkdir::WalkDir; const IMAGE_EXTENSIONS: &[&str] = &[ "jpg", "jpeg", "png", "webp", "avif", "gif", "tiff", "tif", "bmp", "heic", "heif", "jxl", "svg", "ico", ]; fn is_image_extension(ext: &str) -> bool { IMAGE_EXTENSIONS.contains(&ext.to_lowercase().as_str()) } pub fn discover_images(path: &Path, recursive: bool) -> Vec { if path.is_file() { if let Some(ext) = path.extension().and_then(|e| e.to_str()) && is_image_extension(ext) { return vec![path.to_path_buf()]; } return Vec::new(); } if !path.is_dir() { return Vec::new(); } let max_depth = if recursive { usize::MAX } else { 1 }; WalkDir::new(path) .max_depth(max_depth) .into_iter() .filter_map(|entry| entry.ok()) .filter(|entry| entry.file_type().is_file()) .filter(|entry| { entry .path() .extension() .and_then(|ext| ext.to_str()) .is_some_and(is_image_extension) }) .map(|entry| entry.into_path()) .collect() } pub fn has_subdirectories(path: &Path) -> bool { if !path.is_dir() { return false; } std::fs::read_dir(path) .map(|entries| { entries .filter_map(|e| e.ok()) .any(|e| e.file_type().is_ok_and(|ft| ft.is_dir())) }) .unwrap_or(false) }