zoi-rs 1.18.0

Advanced Package Manager & Environment Orchestrator
Documentation
use crate::pkg::install::resolver::InstallNode;
use crate::pkg::install::util;
use crate::pkg::types;
use anyhow::Result;
use rayon::prelude::*;
use std::collections::HashMap;

use std::path::PathBuf;

#[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(
    graph: &HashMap<String, InstallNode>,
    build_type: Option<&str>,
    build: bool,
) -> Result<HashMap<String, InstallAction>> {
    let plan: HashMap<String, InstallAction> = graph
        .par_iter()
        .map(|(id, node)| {
            if build || (build_type.is_some() && build_type != Some("pre-compiled") && build_type != Some("pre-built")) {
                return (id.clone(), InstallAction::BuildAndInstall);
            }

            let action = match util::find_prebuilt_info(node) {
                Ok(Some(info)) => {
                    let (down_size, inst_size) = if let Some(size_url) = &info.size_url {
                        if crate::pkg::offline::is_offline() {
                            (node.pkg.archive_size.unwrap_or(0), node.pkg.installed_size.unwrap_or(0))
                        } else {
                            util::get_expected_size(size_url).unwrap_or_else(|e| {
                                eprintln!(
                                    "Warning: could not fetch size for {}: {}. Falling back to metadata.",
                                    node.pkg.name,
                                    e
                                );
                                (node.pkg.archive_size.unwrap_or(0), node.pkg.installed_size.unwrap_or(0))
                            })
                        }
                    } else {
                        (node.pkg.archive_size.unwrap_or(0), node.pkg.installed_size.unwrap_or(0))
                    };

                    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)
}