rs-hop 0.3.0

Fuzzy-finder TUI to jump between git repositories and folders
Documentation
//! Shared text helpers for the git Standard columns (branch, status, GitHub and
//! ZIP Backup), used by both the flat table and the sectioned view so the two
//! renderers agree without duplicating the cell text.

use std::collections::HashMap;
use std::path::PathBuf;

use chrono::{DateTime, Local};

use crate::domain::repo::{GitInfo, Repo, RepoKind};
use crate::tui::presentation::{IconSet, status_text};

/// The git info to display for `repo`: example info in example mode, otherwise
/// the live info (which may still be loading).
pub fn effective_info(repo: &Repo, example_mode: bool) -> Option<&GitInfo> {
    if example_mode {
        repo.example_git_info.as_ref()
    } else {
        repo.git_info.as_ref()
    }
}

/// The branch text, or a loading marker / dash.
pub fn branch_text(info: Option<&GitInfo>) -> String {
    match info {
        None => "\u{2026}".to_string(),
        Some(info) => info
            .current_branch_name
            .clone()
            .unwrap_or_else(|| "-".to_string()),
    }
}

/// The GitHub name text, or a dash.
pub fn github_text(info: Option<&GitInfo>) -> String {
    info.and_then(|info| info.github_repo_name.clone())
        .unwrap_or_else(|| "-".to_string())
}

/// The plain status text used to size the status column (no colour): a loading
/// marker while unknown, a dash for a missing path, else the formatted status.
pub fn status_display(info: Option<&GitInfo>, icons: &IconSet) -> String {
    match info {
        None => "\u{2026}".to_string(),
        Some(info) if info.is_path_missing() => "-".to_string(),
        Some(info) => status_text(info, icons),
    }
}

/// The ZIP Backup cell text for `repo`: the excluded marker when the entry opts
/// out of the "backup all" run, else the last-backup date (`YYYY-MM-DD`) or a
/// dash when never backed up. Read from the precomputed map (no filesystem I/O).
pub fn zip_date_text(
    repo: &Repo,
    icons: &IconSet,
    zip_backups: &HashMap<PathBuf, DateTime<Local>>,
) -> String {
    if !repo.include_in_backup {
        return icons.excluded.to_string();
    }
    zip_backups
        .get(&repo.path)
        .map_or_else(|| "-".to_string(), |dt| dt.format("%Y-%m-%d").to_string())
}

/// Whether `repo` should show the error marker: a git entry flagged by its
/// gathered info (missing or invalid repository, or the example error in example
/// mode), else `false` (a path entry's marker is driven by the existence check).
pub fn git_marker_errored(repo: &Repo, example_mode: bool) -> bool {
    match repo.kind {
        RepoKind::Git if example_mode => repo.example_error().is_some(),
        RepoKind::Git => repo.entry_error().is_some(),
        RepoKind::Path => false,
    }
}