use std::path::Path;
use anyhow::{bail, Context, Result};
use image::{DynamicImage, GenericImageView, ImageReader};
const SUPPORTED_EXTENSIONS: &[&str] = &["png", "jpg", "jpeg", "tga"];
pub fn load_and_validate_wallpaper(
path: &Path,
terminal_width: u32,
terminal_height: u32,
padding: u32,
) -> Result<DynamicImage> {
if !path.exists() {
bail!("Wallpaper file not found: {}", path.display());
}
if !path.is_file() {
bail!("Wallpaper path is not a file: {}", path.display());
}
let extension = path
.extension()
.and_then(|e| e.to_str())
.map(|e| e.to_lowercase())
.unwrap_or_default();
if !SUPPORTED_EXTENSIONS.contains(&extension.as_str()) {
bail!(
"Unsupported wallpaper format '{}'. Supported formats: {}",
extension,
SUPPORTED_EXTENSIONS.join(", ")
);
}
let wallpaper = ImageReader::open(path)
.with_context(|| format!("Failed to open wallpaper file: {}", path.display()))?
.with_guessed_format()
.with_context(|| "Failed to detect wallpaper image format")?
.decode()
.with_context(|| format!("Failed to decode wallpaper image: {}", path.display()))?;
let (wp_width, wp_height) = wallpaper.dimensions();
let min_width = terminal_width + (padding * 2);
let min_height = terminal_height + (padding * 2);
if wp_width < min_width || wp_height < min_height {
bail!(
"Wallpaper resolution {}x{} is too small.\n\
Required: at least {}x{} (terminal {}x{} + {}px padding on each side).\n\
Please use a larger wallpaper image.",
wp_width,
wp_height,
min_width,
min_height,
terminal_width,
terminal_height,
padding
);
}
Ok(wallpaper)
}
pub fn is_builtin_wallpaper(value: &str) -> bool {
matches!(value.to_lowercase().as_str(), "ventura")
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_is_builtin_wallpaper() {
assert!(is_builtin_wallpaper("ventura"));
assert!(is_builtin_wallpaper("Ventura"));
assert!(is_builtin_wallpaper("VENTURA"));
assert!(!is_builtin_wallpaper("/path/to/file.png"));
assert!(!is_builtin_wallpaper("./wallpaper.jpg"));
assert!(!is_builtin_wallpaper("custom"));
}
}