Set scaling mode from args and configs
This commit is contained in:
parent
84186d3d66
commit
7fc8c0051f
@ -7,7 +7,7 @@ use std::path::PathBuf;
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct Config {
|
||||
pub background_image: String,
|
||||
pub mode: Option<String>, // Unused now, deal with it later
|
||||
pub mode: Option<String>,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
|
||||
@ -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<config::Config>,
|
||||
) -> Result<WallpaperSettings> {
|
||||
// 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 {
|
||||
// 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::<wallpaper::ScalingMode>()
|
||||
.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::<wallpaper::ScalingMode>()
|
||||
.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 })
|
||||
}
|
||||
|
||||
@ -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<Self> {
|
||||
// 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)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user