wallswitch 0.55.0

randomly selects wallpapers for multiple monitors
Documentation
use crate::{Colors, FileInfo, SliceDisplay, WallSwitchResult};
use serde::{Deserialize, Serialize};
use std::str::FromStr;

#[derive(Debug, Clone, Copy, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum SortCriteria {
    Path,
    Size,
    Name,
    Extension,
}

impl FromStr for SortCriteria {
    type Err = String;
    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s.to_lowercase().as_str() {
            "path" => Ok(Self::Path),
            "size" => Ok(Self::Size),
            "name" => Ok(Self::Name),
            "extension" => Ok(Self::Extension),
            _ => Err("Invalid sort criteria. Use: path, size, name, extension".to_string()),
        }
    }
}

/// Sorts and displays all found images based on the chosen criteria, then exits.
pub fn list_all_images(mut images: Vec<FileInfo>, criteria: SortCriteria) -> WallSwitchResult<()> {
    match criteria {
        SortCriteria::Size => {
            images.sort_by_key(|f| f.size);
            println!("Listing images sorted by {}:", "SIZE".yellow().bold());
        }
        SortCriteria::Path => {
            images.sort_by(|a, b| a.path.cmp(&b.path));
            println!("Listing images sorted by {}:", "PATH".yellow().bold());
        }
        SortCriteria::Name => {
            images.sort_by(|a, b| {
                let name_a = a.path.file_name().unwrap_or_default();
                let name_b = b.path.file_name().unwrap_or_default();
                name_a.cmp(name_b)
            });
            println!("Listing images sorted by {}:", "FILE NAME".yellow().bold());
        }
        SortCriteria::Extension => {
            images.sort_by(|a, b| {
                let ext_a = a.path.extension().unwrap_or_default();
                let ext_b = b.path.extension().unwrap_or_default();
                // Sort by extension, and then by name if extensions are equal
                ext_a.cmp(ext_b).then_with(|| {
                    a.path
                        .file_name()
                        .unwrap_or_default()
                        .cmp(b.path.file_name().unwrap_or_default())
                })
            });
            println!("Listing images sorted by {}:", "EXTENSION".yellow().bold());
        }
    }

    // Reuse your existing SliceDisplay for consistent formatting
    // We need to update the numbers (index) based on the new sort order
    let total = images.len();
    for (i, img) in images.iter_mut().enumerate() {
        img.number = i + 1;
        img.total = total;
    }

    print!("{}", SliceDisplay(&images));

    println!("\nTotal images found: {}", total.to_string().green().bold());
    Ok(())
}