From 7fc8c0051ff498b57757dc3a19a9799903f0a039 Mon Sep 17 00:00:00 2001 From: candifloss Date: Thu, 18 Dec 2025 13:38:02 +0530 Subject: [PATCH] Set scaling mode from args and configs --- src/config.rs | 2 +- src/settings.rs | 52 +++++++++++++++++++++++++++++++++++++++--------- src/wallpaper.rs | 22 +++++++++++++++----- 3 files changed, 61 insertions(+), 15 deletions(-) diff --git a/src/config.rs b/src/config.rs index c211d28..0c143f7 100644 --- a/src/config.rs +++ b/src/config.rs @@ -7,7 +7,7 @@ use std::path::PathBuf; #[derive(Debug, Deserialize, Serialize)] pub struct Config { pub background_image: String, - pub mode: Option, // Unused now, deal with it later + pub mode: Option, } impl Config { diff --git a/src/settings.rs b/src/settings.rs index ec8dcc0..121f0b8 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -1,4 +1,4 @@ -use anyhow::Result; +use anyhow::{Context, Result}; use std::path::PathBuf; use crate::{args, config, wallpaper}; @@ -12,6 +12,13 @@ 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. @@ -21,10 +28,16 @@ pub fn resolve_wallpaper( // Case: arg `--update`. Persist wallpaper path to config (create if missing), then apply it. (None, Some(path)) => { - let cfg = config.unwrap_or_else(|| config::Config { - background_image: String::new(), - mode: None, - }); + // 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( @@ -37,21 +50,42 @@ pub fn resolve_wallpaper( // Case: No args. Fallback to config file. (None, None) => { - let cfg = config.ok_or_else(|| { + 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.into() + cfg.background_image.clone().into() } // Case: Both args `--set` & `--update`. This case is already rejected during argument parsing. _ => unreachable!(), }; - //let mode = wallpaper::ScalingMode::Stretch; // - let mode = wallpaper::ScalingMode::Fill; // Default + // 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 }) } diff --git a/src/wallpaper.rs b/src/wallpaper.rs index 8910d1b..9344889 100644 --- a/src/wallpaper.rs +++ b/src/wallpaper.rs @@ -1,15 +1,26 @@ use anyhow::{Context, Result}; use image::{RgbaImage, imageops}; -use std::path::Path; +use std::{path::Path, str::FromStr}; /// Supported wallpaper scaling modes. -/// -/// Others are defined so the public API does not need to change later. #[derive(Debug, Clone, Copy)] pub enum ScalingMode { Stretch, Fill, - // Fit, +} + +impl FromStr for ScalingMode { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result { + // Accept human-friendly strings from CLI / config. + // Case-insensitive to reduce user friction. + match s.to_lowercase().as_str() { + "fill" => Ok(ScalingMode::Fill), + "stretch" => Ok(ScalingMode::Stretch), + _ => Err(anyhow::anyhow!("Invalid wallpaper mode: {s}")), + } + } } /// Result of preparing a wallpaper image for the screen. @@ -116,9 +127,10 @@ pub fn prepare_wallpaper( .with_context(|| format!("Failed to open image: {}", image_path.display()))? .to_rgba8(); + // Scaling mode let prepared = match mode { + ScalingMode::Fill => prepare_fill(&img, screen_width, screen_height), // Default ScalingMode::Stretch => prepare_stretch(&img, screen_width, screen_height), - ScalingMode::Fill => prepare_fill(&img, screen_width, screen_height), }; Ok(prepared)