eazygit 0.5.1

A fast TUI for Git with staging, conflicts, rebase, and palette-first UX
Documentation
//! Selectors for efficient state access.
//!
//! Provides computed values from state with memoization support,
//! following the selector pattern from Redux/Reselect.

use crate::app::AppState;
use crate::git::parsers::status::StatusEntry;

/// Get the count of staged files.
pub fn staged_count(state: &AppState) -> usize {
    state.status_entries.iter().filter(|e| e.staged).count()
}

/// Get the count of unstaged files.
pub fn unstaged_count(state: &AppState) -> usize {
    state.status_entries.iter().filter(|e| e.unstaged).count()
}

/// Check if there are any staged changes.
pub fn has_staged_changes(state: &AppState) -> bool {
    state.status_entries.iter().any(|e| e.staged)
}

/// Check if there are any unstaged changes.
pub fn has_unstaged_changes(state: &AppState) -> bool {
    state.status_entries.iter().any(|e| e.unstaged)
}

/// Get the current branch name.
pub fn current_branch(state: &AppState) -> Option<&str> {
    state.branches.iter()
        .find(|b| !b.is_remote)
        .map(|b| b.name.as_str())
}

/// Check if on main/master branch.
pub fn is_on_main_branch(state: &AppState) -> bool {
    current_branch(state)
        .map(|b| b == "main" || b == "master")
        .unwrap_or(false)
}

/// Get selected status entry.
pub fn selected_status_entry(state: &AppState) -> Option<&StatusEntry> {
    state.status_entries.get(state.status_selected)
}

/// Get selected commit.
pub fn selected_commit(state: &AppState) -> Option<&crate::app::state::CommitEntry> {
    state.commits.get(state.commit_selected)
}

/// Get status summary string.
pub fn status_summary(state: &AppState) -> String {
    let staged = staged_count(state);
    let unstaged = unstaged_count(state);
    
    let mut parts = Vec::new();
    if staged > 0 {
        parts.push(format!("{}+", staged));
    }
    if unstaged > 0 {
        parts.push(format!("{}~", unstaged));
    }
    
    if parts.is_empty() {
        "clean".to_string()
    } else {
        parts.join(" ")
    }
}

/// Check if commit is ready (has staged changes and message).
pub fn can_commit(state: &AppState) -> bool {
    has_staged_changes(state) && !state.commit_input.is_empty()
}

/// Check if app is running.
pub fn is_running(state: &AppState) -> bool {
    state.running
}

// Tests require AppState construction which is complex.
// See integration tests for selector testing.