use std::collections::HashMap;
use std::path::PathBuf;
use anyhow::Result;
use rayon::prelude::*;
use zoi_core::types;
use crate::resolver::InstallNode;
use crate::util;
#[derive(Clone)]
pub struct PrebuiltDetails {
pub info: types::PrebuiltInfo,
pub download_size: u64,
pub installed_size: u64
}
#[derive(Clone)]
pub enum InstallAction {
DownloadAndInstall(PrebuiltDetails),
InstallFromArchive(PathBuf),
BuildAndInstall
}
pub fn create_install_plan<S: std::hash::BuildHasher + Sync>(
graph: &HashMap<String, InstallNode, S>,
build_type: Option<&str>,
build: bool
) -> Result<HashMap<String, InstallAction>> {
let plan: HashMap<String, InstallAction> = graph
.par_iter()
.map(|(id, node)| {
let is_archive = std::path::Path::new(&node.source)
.extension()
.is_some_and(|ext| {
ext.eq_ignore_ascii_case("zpa")
|| ext.eq_ignore_ascii_case("zsa")
});
if (build
|| (build_type.is_some()
&& build_type != Some("pre-compiled")
&& build_type != Some("pre-built")))
&& !is_archive
{
return (id.clone(), InstallAction::BuildAndInstall);
}
if is_archive {
return (
id.clone(),
InstallAction::InstallFromArchive(PathBuf::from(
&node.source
))
);
}
let action = match util::find_prebuilt_info(node) {
Ok(Some(info)) => {
let (down_size, inst_size) = util::get_package_sizes(
&node.pkg,
&node.registry_handle,
&node.version
);
InstallAction::DownloadAndInstall(PrebuiltDetails {
info,
download_size: down_size,
installed_size: inst_size
})
}
Ok(None) => InstallAction::BuildAndInstall,
Err(e) => {
eprintln!(
"Error finding prebuilt info for {}: {}. Assuming \
build.",
node.pkg.name, e
);
InstallAction::BuildAndInstall
}
};
(id.clone(), action)
})
.collect();
Ok(plan)
}