cargo-port 0.1.4

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

use crate::project::AbsolutePath;
use crate::project::Visibility::Deleted;
use crate::project::Visibility::Visible;
use crate::scan::DirSizes;
use crate::tui::app::App;
impl App {
    pub fn handle_disk_usage(&mut self, path: &Path, bytes: u64) {
        self.apply_disk_usage(path, bytes);
    }
    pub(super) fn handle_disk_usage_batch(&mut self, entries: Vec<(AbsolutePath, DirSizes)>) {
        for (path, sizes) in entries {
            self.apply_disk_usage_breakdown(path.as_path(), sizes);
        }
    }
    /// Apply a [`DirSizes`] breakdown to the matching project. Shares
    /// the post-set logic with `apply_disk_usage` (visibility /
    /// lint-runtime registration) by reusing that helper for the
    /// total — the breakdown fields are stored alongside.
    pub(super) fn apply_disk_usage_breakdown(&mut self, path: &Path, sizes: DirSizes) {
        if let Some(project) = self.project_list.at_path_mut(path) {
            project.in_project_target = Some(sizes.in_project_target);
            project.in_project_non_target = Some(sizes.in_project_non_target);
        }
        self.apply_disk_usage(path, sizes.total);
    }
    pub(super) fn apply_disk_usage(&mut self, path: &Path, bytes: u64) {
        // Set disk usage on the matching project item and update visibility.
        let mut lint_runtime_changed = false;
        if let Some(project) = self.project_list.at_path_mut(path) {
            project.disk_usage_bytes = Some(bytes);
            if bytes == 0 && !path.exists() && project.visibility != Deleted {
                project.visibility = Deleted;
                lint_runtime_changed = true;
            } else if bytes > 0 && project.visibility != Visible {
                project.visibility = Visible;
                lint_runtime_changed = true;
            }
        }
        if lint_runtime_changed {
            if let Some(runtime) = self.lint.runtime()
                && bytes == 0
            {
                runtime.unregister_project(AbsolutePath::from(path));
            }
            if bytes > 0 {
                self.register_lint_for_path(path);
            }
        }
    }
    pub(super) fn handle_disk_usage_msg(&mut self, path: &Path, bytes: u64) {
        self.startup.disk.seen.insert(AbsolutePath::from(path));
        self.handle_disk_usage(path, bytes);
        self.maybe_log_startup_phase_completions();
    }
    pub(super) fn handle_disk_usage_batch_msg(
        &mut self,
        root_path: &AbsolutePath,
        entries: Vec<(AbsolutePath, DirSizes)>,
    ) {
        self.scan.bump_generation();
        // Every path inside this tree counts as "seen" — not just
        // the tree root. `group_disk_usage_trees` folds nested
        // discovered projects (workspace members, linked
        // worktrees, etc.) under their shallowest ancestor as
        // `root_path` and lists the rest in `entries`. When the
        // startup-disk phase's `expected` set was built from
        // `ProjectList::iter()` (after `build_tree` consolidated
        // workspaces and worktree groups) but the disk-usage
        // scan was dispatched from phase-1's flat
        // `disk_entries`, the two sources can disagree about
        // what's "the" root. Marking only `root_path` leaves any
        // expected path that ends up listed in `entries` stuck
        // pending in the panel row forever; marking all of them is
        // a no-op for keys that aren't tracked.
        self.startup.disk.seen.insert(root_path.clone());
        for (path, sizes) in &entries {
            if path != root_path {
                self.startup.disk.seen.insert(path.clone());
            }
            if let Some(mtime) = sizes.max_source_mtime {
                self.startup.source_mtimes.insert(path.clone(), mtime);
            }
        }
        self.handle_disk_usage_batch(entries);
        self.maybe_log_startup_phase_completions();
    }
}