use rand::prelude::IndexedRandom;
use std::path::{Path, PathBuf};
use walkdir::WalkDir;
pub struct WallpaperCache {
files: Vec<PathBuf>,
}
impl WallpaperCache {
pub fn new<P: AsRef<Path>>(dir: P) -> anyhow::Result<Self> {
crate::theme::ensure_theme_exists()?;
let mut files = Vec::new();
for entry in WalkDir::new(dir) {
let entry = entry?;
if !entry.file_type().is_file() {
continue;
}
let path = entry.path();
let Some(ext) = path.extension().and_then(|s| s.to_str()) else {
continue;
};
let is_supported = ext.eq_ignore_ascii_case("jpg")
|| ext.eq_ignore_ascii_case("jpeg")
|| ext.eq_ignore_ascii_case("png")
|| ext.eq_ignore_ascii_case("bmp")
|| ext.eq_ignore_ascii_case("webp");
if !is_supported {
continue;
}
let Ok(abs) = path.canonicalize() else {
continue;
};
files.push(abs);
}
if files.is_empty() {
anyhow::bail!("No supported images found in directory.");
}
log::info!("Cached {} wallpapers.", files.len());
Ok(Self { files })
}
pub fn pick_random(&self) -> &Path {
let mut rng = rand::rng();
self.files
.choose(&mut rng)
.expect("WallpaperCache is non-empty after new()")
.as_path()
}
}