ssrm 1.0.0

CLI tool to remove macOS screenshots and screen recordings
Documentation
use owo_colors::OwoColorize;
use ssrm::{Config, ConfigFile, confirm, find_files, format_bytes, parse_date, remove_files};
use std::{env, path::PathBuf};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let args: Vec<String> = env::args().collect();
    
    if args.iter().any(|a| a == "-h" || a == "--help") {
        print_help();
        return Ok(());
    }
    
    let has = |short: &str, long: &str| args.iter().any(|a| a == short || a == long);
    let get_opt = |name: &str| args.windows(2).find(|w| w[0] == name).map(|w| w[1].as_str());
    
    let cfg = Config {
        dry_run: has("-n", "--dry-run"),
        use_trash: has("-t", "--move-to-trash"),
        include_videos: has("-v", "--videos"),
        skip_confirm: has("-f", "--force") || has("-y", "--yes"),
        recursive: has("-r", "--recursive"),
        quiet: has("-q", "--quiet"),
        verbose: has("-V", "--verbose"),
        before: get_opt("--before").and_then(parse_date),
        after: get_opt("--after").and_then(parse_date),
        default_dir: None,
    }.with_file_defaults(ConfigFile::load());
    
    let expand_path = |a: &str| if a.starts_with('~') {
        dirs::home_dir().expect("No home").join(a.strip_prefix("~/").unwrap_or(""))
    } else { PathBuf::from(a) };
    
    let target = args.iter().skip(1)
        .find(|a| !a.starts_with('-') && parse_date(a).is_none())
        .map(|a| expand_path(a))
        .or(cfg.default_dir.clone())
        .unwrap_or_else(|| dirs::desktop_dir().expect("No desktop"));

    let files = find_files(&target, &cfg)?;
    
    if files.is_empty() {
        if !cfg.quiet {
            println!("No screenshots{} found in {}{}.", 
                if cfg.include_videos { "/recordings" } else { "" },
                target.display(),
                if cfg.recursive { " (recursive)" } else { "" });
        }
        return Ok(());
    }

    let label = if cfg.include_videos { "file" } else { "screenshot" };
    let total_size: u64 = files.iter().filter_map(|p| p.metadata().ok()).map(|m| m.len()).sum();
    
    if !cfg.quiet { println!("Found {} {}(s) ({}):", files.len(), label, format_bytes(total_size)); }
    
    if cfg.dry_run {
        if !cfg.quiet {
            for path in &files {
                println!("  {} {}", "[dry-run]".cyan(), path.file_name().unwrap().to_string_lossy());
            }
            println!("\nRun without -n to delete.");
        }
    } else if cfg.skip_confirm || confirm(&format!(
        "{} {} {}(s){}? [y/N] ",
        if cfg.use_trash { "Move" } else { "Permanently delete" },
        files.len(), label,
        if cfg.use_trash { " to trash" } else { "" }
    )) {
        let stats = remove_files(&files, &cfg);
        if !cfg.quiet {
            let action = if cfg.use_trash { "Trashed" } else { "Removed" };
            println!("\n{} {} {}(s). Freed {}.", action, stats.removed, label, format_bytes(stats.bytes_freed));
        }
    } else if !cfg.quiet {
        println!("Aborted.");
    }
    Ok(())
}

fn print_help() {
    println!("ssrm - Remove macOS screenshots/recordings\n");
    println!("Usage: ssrm [DIR] [OPTIONS]\n");
    println!("Arguments:");
    println!("  [DIR]              Target directory (default: Desktop)\n");
    println!("Options:");
    println!("  -n, --dry-run      Show what would be deleted without deleting");
    println!("  -t, --move-to-trash Move to trash instead of permanent deletion");
    println!("  -v, --videos       Include screen recordings");
    println!("  -f, --force        Skip confirmation prompt");
    println!("  -y, --yes          Alias for --force");
    println!("  -r, --recursive    Search directories recursively");
    println!("  -q, --quiet        Suppress output (for scripting)");
    println!("  -V, --verbose      Show detailed debug output");
    println!("  --before DATE      Only files before DATE (YYYY-MM-DD)");
    println!("  --after DATE       Only files after DATE (YYYY-MM-DD)");
    println!("  -h, --help         Show this help\n");
    println!("Config: ~/.config/ssrm.toml");
    println!("  use_trash = true       # Always use trash");
    println!("  include_videos = true  # Include recordings");
    println!("  recursive = true       # Search recursively");
    println!("  default_dir = \"~/...\"  # Default target directory");
}