use anyhow::{Context, Result}; use std::path::PathBuf; use crate::{args, config, wallpaper}; pub struct WallpaperSettings { pub path: PathBuf, pub mode: wallpaper::ScalingMode, } pub fn resolve_wallpaper( args: &args::Args, config: Option, ) -> Result { // Borrow the config once as `Option<&Config>`. // // Avoids moving `config`, allows to: // - read values multiple times // - decide later whether we need to write a new config let cfg_ref = config.as_ref(); // Resolve wallpaper image path by precedence: // 1. args (`--set`, `--update`): Use path from args. // 2. config: Use path from config. let path = match (&args.set, &args.update) { // Case: arg `--set`: One-shot wallpaper change. Not persistent. (Some(path), None) => path.clone(), // Case: arg `--update`. Persist wallpaper path to config (create if missing), then apply it. (None, Some(path)) => { // Use existing config if present. // Otherwise, create a minimal temporary config only for writing. // Avoids moving or cloning the original config, keeps ownership simple. let cfg = match cfg_ref { Some(cfg) => cfg, None => &config::Config { background_image: String::new(), mode: None, }, }; // Write to config. cfg.update_background_image( path.to_str() // Unsupported path format. .ok_or_else(|| anyhow::anyhow!("Non-UTF8 path"))?, )?; path.clone() } // Case: No args. Fallback to config file. (None, None) => { let cfg = cfg_ref.ok_or_else(|| { // No CLI args and no valid config. anyhow::anyhow!("No or invalid image path specified in config or args.") })?; // Successfully loaded. cfg.background_image.clone().into() } // Case: Both args `--set` & `--update`. This case is already rejected during argument parsing. _ => unreachable!(), }; // Resolve scaling mode by precedence: // 1. CLI argument (`--mode`) if provided // 2. Config file value if present // 3. Default to Fill let mode = if let Some(mode_arg) = &args.mode { // CLI has highest priority mode_arg .parse::() .with_context(|| "Invalid wallpaper mode in CLI")? } else if let Some(cfg) = cfg_ref { if let Some(mode_str) = &cfg.mode { // Config-specified mode mode_str .parse::() .with_context(|| "Invalid wallpaper mode in config")? } else { // Config exists, but mode not specified wallpaper::ScalingMode::Fill } } else { // No CLI and no config → default wallpaper::ScalingMode::Fill }; Ok(WallpaperSettings { path, mode }) }