knott 0.1.7

Fast Rust package manager helper for Arch Linux repos and the AUR
Documentation
use crate::aur::{AurClient, AurPackage};
use crate::cli::Options;
use crate::output;
use crate::pacman::Toolchain;
use anyhow::Result;
use std::collections::HashSet;

pub async fn print_info(
    options: &Options,
    tools: &Toolchain,
    aur: &AurClient,
    targets: &[String],
) -> Result<i32> {
    if targets.is_empty() {
        return Ok(1);
    }

    let mut missing = Vec::new();
    let mut printed = false;

    if options.mode.repo() {
        for target in targets {
            if let Some(output) = tools.repo_info(target).await? {
                print_separator(printed);
                output::block(&output);
                printed = true;
            } else {
                missing.push(target.clone());
            }
        }
    } else {
        missing.extend(targets.iter().cloned());
    }

    if options.mode.aur() {
        let aur_targets = if options.mode.repo() {
            missing
        } else {
            targets.to_vec()
        };
        let found = aur.info(&aur_targets).await?;
        let found_names = found
            .iter()
            .map(|pkg| pkg.name.clone())
            .collect::<HashSet<_>>();

        for pkg in found {
            print_separator(printed);
            print_aur_package(aur, &pkg);
            printed = true;
        }

        for target in aur_targets {
            if !found_names.contains(&target) {
                output::error(format!("package '{target}' was not found"));
            }
        }
    }

    Ok((!printed) as i32)
}

fn print_separator(printed: bool) {
    if printed {
        println!();
    }
}

pub fn print_aur_package(aur: &AurClient, pkg: &AurPackage) {
    output::field("Repository", "aur");
    output::field("AUR ID", pkg.id.to_string());
    output::field("Name", &pkg.name);
    output::field("Version", &pkg.version);
    output::field("Description", pkg.description.as_deref().unwrap_or("None"));
    output::field("URL", pkg.url.as_deref().unwrap_or("None"));
    output::field("AUR URL", aur.web_url(&pkg.name));
    output::field("Package Base", pkg.base());
    output::field("Package Base ID", pkg.package_base_id.to_string());
    output::field("Votes", pkg.num_votes.to_string());
    output::field("Popularity", format!("{:.6}", pkg.popularity));
    output::field("Maintainer", pkg.maintainer.as_deref().unwrap_or("None"));
    output::field("First Submitted", pkg.first_submitted.to_string());
    output::field(
        "Out Of Date",
        pkg.out_of_date
            .map_or("No".to_string(), |ts| ts.to_string()),
    );
    output::field("Depends On", list(&pkg.depends));
    output::field("Make Depends", list(&pkg.make_depends));
    output::field("Check Depends", list(&pkg.check_depends));
    output::field("Optional Deps", list(&pkg.opt_depends));
    output::field("Provides", list(&pkg.provides));
    output::field("Conflicts With", list(&pkg.conflicts));
    output::field("License", list(&pkg.license));
    output::field("Keywords", list(&pkg.keywords));
}

fn list(values: &[String]) -> String {
    if values.is_empty() {
        "None".to_string()
    } else {
        output::join_inline(values, "  ")
    }
}