use crate::checks::{check_cargo_quiet, merge_check_result};
use crate::command::run_inherit;
use crate::dashboard;
use crate::flow::check::{cargo_binstall_missing, cargo_update_missing};
use crate::output::{err_text, print_exit_signal_message, print_section, warn_text};
use crate::profile::{interactive_terminal, parse_profile};
use crate::selection::{confirm_default_yes, resolve_cli_selection_quiet};
use crate::state::{AppState, section_title};
pub enum InteractiveResult {
Exit(i32),
}
pub async fn run_interactive_flow(
state: &mut AppState,
requested_updates: &[String],
start_time: &str,
) -> std::io::Result<InteractiveResult> {
let code = dashboard::run(state, requested_updates, start_time).await?;
Ok(InteractiveResult::Exit(code))
}
pub async fn offer_install_cargo_update(state: &mut AppState) {
if !interactive_terminal() || !cargo_update_missing(state).await {
return;
}
print_section("cargo-update");
println!("未安装 cargo-install-update, 无法检查已安装 crate 更新.");
if !confirm_cargo_update_install_text().await {
return;
}
println!("[cargo] 正在执行: cargo install cargo-update");
let install_result = run_inherit("cargo", &["install", "cargo-update"]).await;
handle_cargo_update_install_text_result(state, install_result).await;
}
pub async fn offer_install_cargo_binstall(state: &AppState) {
if !interactive_terminal() || !cargo_binstall_missing(state).await {
return;
}
print_section("cargo-binstall");
println!("未安装 cargo-binstall.");
println!("建议安装它, 以便 cargo 管理的软件可优先使用预编译二进制快速安装或升级.");
if !confirm_cargo_binstall_install_text().await {
return;
}
println!("[cargo] 正在执行: cargo install cargo-binstall");
match run_inherit("cargo", &["install", "cargo-binstall"]).await {
Ok(true) => println!("[cargo] cargo-binstall 安装完成."),
_ => println!("{}", err_text("[cargo] cargo-binstall 安装失败.")),
}
}
async fn confirm_cargo_update_install_text() -> bool {
match confirm_default_yes("是否执行 cargo install cargo-update").await {
Some(true) => true,
Some(false) => {
println!("{}", warn_text("已跳过 cargo-update 安装."));
false
}
None => exit_after_interrupted_prompt(),
}
}
async fn confirm_cargo_binstall_install_text() -> bool {
match confirm_default_yes("是否执行 cargo install cargo-binstall").await {
Some(true) => true,
Some(false) => {
println!("{}", warn_text("已跳过 cargo-binstall 安装."));
false
}
None => exit_after_interrupted_prompt(),
}
}
fn exit_after_interrupted_prompt() -> ! {
print_exit_signal_message();
std::process::exit(0);
}
async fn handle_cargo_update_install_text_result(
state: &mut AppState,
install_result: std::io::Result<bool>,
) {
if let Ok(true) = install_result {
println!("[cargo] cargo-update 安装完成, 正在重新检查 cargo.");
let logs = recheck_cargo_after_update_install(state).await;
print_section(section_title("cargo"));
print_lines(logs);
return;
}
state.cargo.check_failed = true;
println!("{}", err_text("[cargo] cargo-update 安装失败."));
}
async fn recheck_cargo_after_update_install(state: &mut AppState) -> Vec<String> {
state.cargo.has_updates = false;
state.cargo.check_failed = false;
state.cargo.updater_installed = false;
state.cargo.updatable_packages.clear();
let mut logs = Vec::new();
let mut local = AppState::default();
parse_profile(&mut local).await;
check_cargo_quiet(&mut local, &mut logs).await;
merge_check_result(state, "cargo", local);
logs
}
fn print_lines(lines: Vec<String>) {
for line in lines {
println!("{line}");
}
}
#[allow(dead_code)]
fn selected_cli_targets(
requested_updates: &[String],
upgradable_targets: &[String],
) -> Vec<String> {
resolve_cli_selection_quiet(requested_updates, upgradable_targets).0
}