use std::path::Path;
use tui_pane::Appearance;
use crate::http::ServiceSignal;
use crate::project::AbsolutePath;
use crate::project::RootItem;
use crate::project::Submodule;
use crate::scan::BackgroundMsg;
use crate::tui::app::App;
use crate::tui::app::scan_state::ScanPhase;
use crate::tui::project_list::ProjectList;
impl App {
pub(super) fn update_generations_for_msg(&mut self, msg: &BackgroundMsg) {
if let Some(path) = msg.detail_relevance()
&& self.detail_path_is_affected(path)
{
self.scan.bump_generation();
}
}
pub(super) fn handle_scan_result(
&mut self,
projects: Vec<RootItem>,
disk_entries: &[(String, AbsolutePath)],
) {
let kind = if self.scan.state.run_count == 1 {
"initial"
} else {
"rescan"
};
tracing::trace!(
target: tui_pane::PERF_LOG_TARGET,
elapsed_ms = tui_pane::perf_log_ms(self.scan.state.started_at.elapsed().as_millis()),
kind,
run = self.scan.state.run_count,
tree_items = projects.len(),
disk_entries = disk_entries.len(),
"scan_result_applied"
);
let selected_path = self
.project_list
.selected_project_path()
.map(AbsolutePath::from)
.or_else(|| self.project_list.paths.last_selected.clone());
self.mutate_tree().replace_all(ProjectList::new(projects));
self.prune_inactive_project_state();
let lint_registered = self.register_lint_for_root_items();
self.refresh_lint_runs_from_disk();
self.scan.bump_generation();
let pending = std::mem::take(&mut self.project_list.paths.pending_expanded);
self.project_list.apply_expanded(&pending);
self.rebuild_visible_rows_now();
if let Some(path) = selected_path {
self.project_list.select_project_in_tree(
path.as_path(),
self.config.include_non_rust().includes_non_rust(),
);
} else if !self.project_list.is_empty() {
self.project_list.set_cursor(0);
}
self.sync_selected_project();
self.register_background_services_for_tree();
self.finish_watcher_registration_batch();
self.scan.state.phase = ScanPhase::Complete;
self.begin_startup_phase(lint_registered);
}
#[allow(
clippy::too_many_lines,
reason = "trivial 1:1 exhaustive variant mapping"
)]
pub fn handle_bg_msg(&mut self, msg: BackgroundMsg) -> bool {
self.update_generations_for_msg(&msg);
match msg {
BackgroundMsg::DiskUsage { path, bytes } => {
self.handle_disk_usage_msg(path.as_path(), bytes);
},
BackgroundMsg::DiskUsageBatch { root_path, entries } => {
self.handle_disk_usage_batch_msg(&root_path, entries);
},
BackgroundMsg::CiRuns {
path,
runs,
github_total,
} => self.insert_ci_runs(path.as_path(), runs, github_total),
BackgroundMsg::RepoFetchQueued { repo } => self.handle_repo_fetch_queued(repo),
BackgroundMsg::RepoFetchComplete { repo } => self.handle_repo_fetch_complete(repo),
BackgroundMsg::PullRequests { repo, data } => {
self.handle_pull_requests(&repo, &data);
},
BackgroundMsg::PullRequestCheckPollStopped { repo, number } => {
self.handle_pull_request_check_poll_stopped(&repo, number);
},
BackgroundMsg::PullRequestDisappeared {
repo,
pull_request,
reason,
} => {
self.handle_pull_request_disappeared(&repo, &pull_request, &reason);
},
BackgroundMsg::CratesIoFetchQueued { name } => {
self.handle_crates_io_fetch_queued(name);
},
BackgroundMsg::CratesIoFetchComplete { name } => {
self.handle_crates_io_fetch_complete(&name);
},
BackgroundMsg::CheckoutInfo { path, info } => {
self.handle_checkout_info(path.as_path(), info);
},
BackgroundMsg::RepoInfo { path, info } => {
self.handle_repo_info(path.as_path(), info);
},
BackgroundMsg::GitFirstCommit { path, first_commit } => {
self.handle_git_first_commit(path.as_path(), first_commit.as_deref());
},
BackgroundMsg::ProjectDetailsDeclared { path } => {
self.mark_startup_project_details_declared(path);
},
BackgroundMsg::Submodules { path, submodules } => {
self.handle_submodules_msg(path.as_path(), submodules);
},
BackgroundMsg::CratesIoVersion {
path,
version,
prerelease,
downloads,
} => self.project_list.handle_crates_io_version_msg(
path.as_path(),
version,
prerelease,
downloads,
),
BackgroundMsg::RepoMeta {
path,
stars,
description,
} => self
.project_list
.handle_repo_meta(path.as_path(), stars, description),
BackgroundMsg::ScanResult {
projects,
disk_entries,
} => self.handle_scan_result(projects, &disk_entries),
BackgroundMsg::ProjectDiscovered { item } => {
return self.handle_project_discovered(item);
},
BackgroundMsg::ProjectRefreshed { item } => return self.handle_project_refreshed(item),
BackgroundMsg::LintCachePruned {
runs_evicted,
bytes_reclaimed,
} => self.handle_lint_cache_pruned(runs_evicted, bytes_reclaimed),
BackgroundMsg::LintCacheUsage { usage } => self.lint.set_cache_usage(usage),
BackgroundMsg::LintHistoryLoaded { entries } => {
self.apply_lint_history_loaded(entries);
},
BackgroundMsg::LintStatus {
path,
status,
origin,
} => {
self.handle_lint_status_msg(path.as_path(), status, origin);
},
BackgroundMsg::LintStartupStatus { path, status } => {
self.handle_lint_startup_status_msg(&path, status);
},
BackgroundMsg::ServiceReachable { service } => {
self.apply_service_signal(ServiceSignal::Reachable(service));
},
BackgroundMsg::ServiceRecovered { service } => self.mark_service_recovered(service),
BackgroundMsg::ServiceUnreachable { service } => {
self.apply_service_signal(ServiceSignal::Unreachable(service));
},
BackgroundMsg::ServiceUnreachableConfirmed { service } => {
self.confirm_service_unreachable(service);
},
BackgroundMsg::ServiceRateLimited { service } => {
self.apply_service_signal(ServiceSignal::RateLimited(service));
},
BackgroundMsg::LanguageStatsProgressPlan { units } => {
self.mark_startup_languages_expected(units);
},
BackgroundMsg::LanguageStatsBatch { entries } => {
self.mark_startup_languages_seen(&entries);
self.project_list.handle_language_stats_batch(entries);
},
BackgroundMsg::TestCountsBatch { entries } => {
self.mark_startup_tests_seen(&entries);
self.project_list.handle_test_counts_batch(entries);
self.scan.bump_generation();
},
BackgroundMsg::SccacheStats { request_id, result } => {
self.overlays.sccache_pane.apply_result(request_id, result);
},
BackgroundMsg::CargoMetadata {
workspace_root,
generation,
fingerprint,
result,
} => self.handle_cargo_metadata_msg(workspace_root, generation, &fingerprint, result),
BackgroundMsg::OutOfTreeTargetSize {
workspace_root,
target_dir,
bytes,
} => self
.scan
.handle_out_of_tree_target_size(&workspace_root, &target_dir, bytes),
BackgroundMsg::AppearanceChanged(appearance) => self.apply_os_appearance(appearance),
}
false
}
fn handle_submodules_msg(&mut self, path: &Path, submodules: Vec<Submodule>) {
if let Some(info) = self.project_list.at_path_mut(path) {
info.submodules = submodules;
}
}
fn apply_os_appearance(&mut self, appearance: Appearance) {
self.themes.set_os_appearance(Some(appearance));
self.resolve_and_apply_active_theme();
}
}