knott 0.1.3

Fast Rust package manager helper for Arch Linux repos and the AUR
Documentation
use crate::aur::{AurClient, AurPackage};
use crate::cli::Options;
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);
                print!("{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) {
                eprintln!("error: 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) {
    println!("Repository      : aur");
    println!("AUR ID          : {}", pkg.id);
    println!("Name            : {}", pkg.name);
    println!("Version         : {}", pkg.version);
    println!(
        "Description     : {}",
        pkg.description.as_deref().unwrap_or("None")
    );
    println!("URL             : {}", pkg.url.as_deref().unwrap_or("None"));
    println!("AUR URL         : {}", aur.web_url(&pkg.name));
    println!("Package Base    : {}", pkg.base());
    println!("Package Base ID : {}", pkg.package_base_id);
    println!("Votes           : {}", pkg.num_votes);
    println!("Popularity      : {:.6}", pkg.popularity);
    println!(
        "Maintainer      : {}",
        pkg.maintainer.as_deref().unwrap_or("None")
    );
    println!("First Submitted : {}", pkg.first_submitted);
    println!(
        "Out Of Date     : {}",
        pkg.out_of_date
            .map_or("No".to_string(), |ts| ts.to_string())
    );
    println!("Depends On      : {}", list(&pkg.depends));
    println!("Make Depends    : {}", list(&pkg.make_depends));
    println!("Check Depends   : {}", list(&pkg.check_depends));
    println!("Optional Deps   : {}", list(&pkg.opt_depends));
    println!("Provides        : {}", list(&pkg.provides));
    println!("Conflicts With  : {}", list(&pkg.conflicts));
    println!("License         : {}", list(&pkg.license));
    println!("Keywords        : {}", list(&pkg.keywords));
}

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