From b05d9c44b45dc9f594a917390eadab4039936af5 Mon Sep 17 00:00:00 2001 From: Azalea <22280294+hykilpikonna@users.noreply.github.com> Date: Tue, 7 Apr 2026 15:50:30 +0000 Subject: [PATCH] [+] Option to select random flags (#487) --- crates/hyfetch/src/bin/hyfetch.rs | 19 +++++++++++++----- crates/hyfetch/src/cli_options.rs | 2 +- crates/hyfetch/src/models.rs | 32 ++++++++++++++++++++++++++++++- 3 files changed, 46 insertions(+), 7 deletions(-) diff --git a/crates/hyfetch/src/bin/hyfetch.rs b/crates/hyfetch/src/bin/hyfetch.rs index 1418b66b..602bfe26 100644 --- a/crates/hyfetch/src/bin/hyfetch.rs +++ b/crates/hyfetch/src/bin/hyfetch.rs @@ -24,7 +24,7 @@ use hyfetch::color_util::{ NeofetchAsciiIndexedColor, PresetIndexedColor, Theme as _, ToAnsiString as _, }; use hyfetch::distros::Distro; -use hyfetch::models::{build_hex_color_profile, Config}; +use hyfetch::models::{build_hex_color_profile, Config, PresetValue}; #[cfg(feature = "macchina")] use hyfetch::neofetch_util::macchina_path; use hyfetch::neofetch_util::{self, add_pkg_path, fastfetch_path, get_distro_ascii, get_distro_name, literal_input, ColorAlignment, NEOFETCH_COLORS_AC, NEOFETCH_COLOR_PATTERNS, TEST_ASCII}; @@ -153,9 +153,15 @@ fn main() -> Result<()> { .collect(); preset_profiles.extend(config.custom_preset_profiles()?); - let presets: Vec = preset_profiles.values().cloned().collect(); + if preset_string.contains(',') { + let presets: Vec<&str> = preset_string.split(',').map(|s| s.trim()).collect(); + let mut rng = fastrand::Rng::new(); + let selected_index = rng.usize(0..presets.len()); + return parse_preset_string(presets[selected_index], config); + } if preset_string == "random" { + let presets: Vec = preset_profiles.values().cloned().collect(); if presets.is_empty() { return Err(anyhow::anyhow!("preset iterator should not be empty")); } @@ -180,8 +186,11 @@ fn main() -> Result<()> { } // Get preset - let preset_string = options.preset.as_deref().unwrap_or(&config.preset); - let color_profile = parse_preset_string(preset_string, &config)?; + let preset_string = options + .preset + .clone() + .unwrap_or_else(|| config.preset.get_random_if_multiple()); + let color_profile = parse_preset_string(&preset_string, &config)?; debug!(?color_profile, "color profile"); // Lighten @@ -1218,7 +1227,7 @@ fn create_config( // Create config clear_screen(Some(&title), color_mode, debug_mode).context("failed to clear screen")?; let config = Config { - preset: preset.as_ref().to_string(), + preset: PresetValue::from(preset.as_ref().to_string()), mode: color_mode, light_dark: Some(theme), auto_detect_light_dark: Some(det_bg.is_some()), diff --git a/crates/hyfetch/src/cli_options.rs b/crates/hyfetch/src/cli_options.rs index 49c3184c..494a770d 100644 --- a/crates/hyfetch/src/cli_options.rs +++ b/crates/hyfetch/src/cli_options.rs @@ -55,7 +55,7 @@ pub fn options() -> OptionParser { let preset = long("preset") .short('p') .help(&*format!( - "Use preset or comma-separated color list or comma-separated hex colors (e.g., \"#ff0000,#00ff00,#0000ff\") + "Use preset or comma-separated color list or comma-separated hex colors (e.g., \"#ff0000,#00ff00,#0000ff\"). Comma-separated preset names will pick one randomly. PRESET={{{presets}}}", presets = ::VARIANTS .iter() diff --git a/crates/hyfetch/src/models.rs b/crates/hyfetch/src/models.rs index ad6962d6..10672bb8 100644 --- a/crates/hyfetch/src/models.rs +++ b/crates/hyfetch/src/models.rs @@ -10,7 +10,7 @@ use crate::types::{AnsiMode, Backend, TerminalTheme}; #[derive(Clone, Debug, Deserialize, Serialize)] pub struct Config { - pub preset: String, + pub preset: PresetValue, pub mode: AnsiMode, pub auto_detect_light_dark: Option, pub light_dark: Option, @@ -156,3 +156,33 @@ mod args_serde { deserializer.deserialize_option(OptionVisitor) } } + +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(untagged)] +pub enum PresetValue { + Single(String), + Multiple(Vec), +} + +impl From for PresetValue { + fn from(s: String) -> Self { + PresetValue::Single(s) + } +} + +impl PresetValue { + pub fn get_random_if_multiple(&self) -> String { + match self { + PresetValue::Single(s) => s.clone(), + PresetValue::Multiple(v) => { + if v.is_empty() { + "random".to_owned() + } else { + let mut rng = fastrand::Rng::new(); + let selected_index = rng.usize(0..v.len()); + v[selected_index].clone() + } + } + } + } +}