cargo-port 0.1.3

A TUI for inspecting and managing Rust projects
use std::path::Path;

use crate::project::AbsolutePath;
use crate::project::RootItem;
use crate::tui::app::App;
use crate::tui::project_list::VisibleRow;
use crate::tui::terminal;

impl App {
    pub(super) fn detail_path_is_affected(&self, path: &Path) -> bool {
        let Some(selected_path) = self.project_list.selected_project_path() else {
            return false;
        };
        if selected_path == path {
            return true;
        }
        if self.selected_worktree_group_contains(path) {
            return true;
        }
        // Check if both paths resolve to the same lint-owning node.
        // This covers shared owner rows such as workspace members
        // without widening unrelated watcher invalidations.
        self.project_list
            .lint_at_path(selected_path)
            .zip(self.project_list.lint_at_path(path))
            .is_some_and(|(a, b)| std::ptr::eq(a, b))
    }

    fn selected_worktree_group_contains(&self, path: &Path) -> bool {
        let Some(VisibleRow::Root { node_index }) = self.project_list.selected_row() else {
            return false;
        };
        let Some(entry) = self.project_list.get(node_index) else {
            return false;
        };
        let RootItem::Worktrees(group) = &entry.item else {
            return false;
        };
        group
            .iter_paths()
            .any(|group_path| group_path.as_path() == path)
    }

    /// Spawn a priority fetch for the selected project if it hasn't been loaded yet.
    pub fn maybe_priority_fetch(&mut self) {
        let Some(abs_path) = self
            .project_list
            .selected_project_path()
            .map(Path::to_path_buf)
        else {
            return;
        };
        let abs_key: AbsolutePath = abs_path.clone().into();
        let display_path = self
            .selected_display_path()
            .unwrap_or_else(|| abs_key.display_path());
        let name = self
            .panes
            .package
            .content()
            .map(|d| d.title_name.clone())
            .filter(|n| n != "-");
        if self
            .project_list
            .at_path(abs_key.as_path())
            .is_none_or(|p| p.disk_usage_bytes.is_none())
            && self.scan.priority_fetch_path() != Some(&abs_key)
        {
            self.scan.set_priority_fetch_path(Some(abs_key));
            let abs_str = abs_path.display().to_string();
            terminal::spawn_priority_fetch(self, display_path.as_str(), &abs_str, name.as_ref());
        }
    }
}