wallswitch 0.60.5

randomly selects wallpapers for multiple monitors
Documentation
use serde::{Deserialize, Serialize};
use std::fmt::{self, Display};

// ANSI Escape Codes for Terminal Text Formatting
// https://gist.github.com/abritinthebay/d80eb99b2726c83feb0d97eab95206c4
// https://talyian.github.io/ansicolors/
const RESET: &str = "\x1b[0m";
const BOLD: &str = "\x1b[1m";
const DIM: &str = "\x1b[2m";
const BLACK: &str = "\x1b[30m";
const RED: &str = "\x1b[31m";
const GREEN: &str = "\x1b[32m";
const YELLOW: &str = "\x1b[33m";
const BLUE: &str = "\x1b[34m";
const MAGENTA: &str = "\x1b[35m";
const CYAN: &str = "\x1b[36m";
const WHITE: &str = "\x1b[37m";

// ANSI Terminal Control Sequences
pub const CURSOR_TO_START: &str = "\r";
pub const ERASE_LINE_TO_END: &str = "\x1b[K";

/// Extension trait providing ANSI text-coloring and styling helpers for stdout.
pub trait Colors {
    // Styles
    fn bold(&self) -> String;
    fn dimmed(&self) -> String;

    // Colors
    fn black(&self) -> String;
    fn red(&self) -> String;
    fn green(&self) -> String;
    fn yellow(&self) -> String;
    fn blue(&self) -> String;
    fn magenta(&self) -> String;
    fn cyan(&self) -> String;
    fn white(&self) -> String;

    /// Wraps the text to be printed on a single line, clearing the previous content.
    /// Idiomatic way to handle progress updates.
    fn to_line_start(&self) -> String;
}

impl<T> Colors for T
where
    T: Display,
{
    fn bold(&self) -> String {
        format!("{BOLD}{self}{RESET}")
    }

    fn dimmed(&self) -> String {
        format!("{DIM}{self}{RESET}")
    }

    fn black(&self) -> String {
        format!("{BLACK}{self}{RESET}")
    }

    fn red(&self) -> String {
        format!("{RED}{self}{RESET}")
    }

    fn green(&self) -> String {
        format!("{GREEN}{self}{RESET}")
    }

    fn yellow(&self) -> String {
        format!("{YELLOW}{self}{RESET}")
    }

    fn blue(&self) -> String {
        format!("{BLUE}{self}{RESET}")
    }

    fn magenta(&self) -> String {
        format!("{MAGENTA}{self}{RESET}")
    }

    fn cyan(&self) -> String {
        format!("{CYAN}{self}{RESET}")
    }

    fn white(&self) -> String {
        format!("{WHITE}{self}{RESET}")
    }

    fn to_line_start(&self) -> String {
        format!("{CURSOR_TO_START}{self}{ERASE_LINE_TO_END}")
    }
}

// ==============================================================================
// GRAPHICS AND IMAGE RENDERING COLOR MODELS
// ==============================================================================

/// Represents a named neon color palette with float-based RGB channels.
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub struct NeonColor {
    /// Red channel value (0.0 to 1.0).
    pub red: f32,
    /// Green channel value (0.0 to 1.0).
    pub green: f32,
    /// Blue channel value (0.0 to 1.0).
    pub blue: f32,
    /// Descriptive name of the color palette.
    pub name: &'static str,
}

impl NeonColor {
    /// Converts the struct's color channels into a raw float array `[red, green, blue]`.
    #[inline]
    pub const fn to_array(&self) -> [f32; 3] {
        [self.red, self.green, self.blue]
    }
}

// Implements Display to format the colors automatically with two decimal places in any print macros
impl fmt::Display for NeonColor {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(
            f,
            "RGB [{:.2}, {:.2}, {:.2}] {}",
            self.red, self.green, self.blue, self.name
        )
    }
}

/// Vibrant, high-contrast color palettes paired with their descriptive names.
/// These 20 colors are specifically chosen to remain highly visible on both
/// extremely light (near-white) and extremely dark (near-black) desktop wallpapers
/// by balancing high saturation with medium-high perceived luminance.
pub const NEON_PALETTES: [NeonColor; 20] = [
    NeonColor {
        red: 1.0,
        green: 0.05,
        blue: 0.55,
        name: "Neon Rose - Punchy Pink",
    },
    NeonColor {
        red: 0.0,
        green: 0.95,
        blue: 0.85,
        name: "Vivid Turquoise - Electric Teal",
    },
    NeonColor {
        red: 0.95,
        green: 0.45,
        blue: 0.0,
        name: "Tangerine Dream - Electric Orange",
    },
    NeonColor {
        red: 0.4,
        green: 0.9,
        blue: 0.0,
        name: "Radioactive Lime - Acid Green",
    },
    NeonColor {
        red: 0.9,
        green: 0.9,
        blue: 0.0,
        name: "Laser Lemon - Bright Yellow",
    },
    NeonColor {
        red: 0.05,
        green: 0.8,
        blue: 1.0,
        name: "Blue Bolt - Intense Sky Cyan",
    },
    NeonColor {
        red: 0.85,
        green: 0.15,
        blue: 1.0,
        name: "Radiant Orchid - Electric Violet",
    },
    NeonColor {
        red: 1.0,
        green: 0.35,
        blue: 0.1,
        name: "Fiery Coral - Sunset Flame",
    },
    NeonColor {
        red: 0.1,
        green: 0.95,
        blue: 0.4,
        name: "Mint Spark - Spring Neon Green",
    },
    NeonColor {
        red: 1.0,
        green: 0.0,
        blue: 0.35,
        name: "Cherry Flare - Electric Ruby",
    },
    NeonColor {
        red: 0.75,
        green: 0.95,
        blue: 0.0,
        name: "Vibrant Chartreuse - Pear Glow",
    },
    NeonColor {
        red: 0.0,
        green: 1.0,
        blue: 0.7,
        name: "Aqua Glow - Supercharged seafoam",
    },
    NeonColor {
        red: 1.0,
        green: 0.55,
        blue: 0.4,
        name: "Warm Apricot - Peach Spark",
    },
    NeonColor {
        red: 0.9,
        green: 0.2,
        blue: 0.9,
        name: "Cyberpunk Fuchsia - Hot Magenta",
    },
    NeonColor {
        red: 0.35,
        green: 1.0,
        blue: 0.5,
        name: "Bright Emerald - Neon Clover",
    },
    NeonColor {
        red: 1.0,
        green: 0.85,
        blue: 0.0,
        name: "Solar Flare - Amber Gold",
    },
    NeonColor {
        red: 0.55,
        green: 0.35,
        blue: 1.0,
        name: "Electric Amethyst - Bright Violet",
    },
    NeonColor {
        red: 1.0,
        green: 0.25,
        blue: 0.5,
        name: "Flamingo Neon - Warm Pink",
    },
    NeonColor {
        red: 0.2,
        green: 0.9,
        blue: 0.9,
        name: "Glacier Cyan - Ice Blue Glow",
    },
    NeonColor {
        red: 0.85,
        green: 1.0,
        blue: 0.2,
        name: "Radioactive Melon - Lemon Lime Flare",
    },
];