knott 0.1.4

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);
                print!("{}", output::text(&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 '{}' was not found", output::inline(&target));
            }
        }
    }

    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            : {}", output::inline(&pkg.name));
    println!("Version         : {}", output::inline(&pkg.version));
    println!(
        "Description     : {}",
        output::inline(pkg.description.as_deref().unwrap_or("None"))
    );
    println!(
        "URL             : {}",
        output::inline(pkg.url.as_deref().unwrap_or("None"))
    );
    println!(
        "AUR URL         : {}",
        output::inline(&aur.web_url(&pkg.name))
    );
    println!("Package Base    : {}", output::inline(pkg.base()));
    println!("Package Base ID : {}", pkg.package_base_id);
    println!("Votes           : {}", pkg.num_votes);
    println!("Popularity      : {:.6}", pkg.popularity);
    println!(
        "Maintainer      : {}",
        output::inline(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
            .iter()
            .map(|value| output::inline(value))
            .collect::<Vec<_>>()
            .join("  ")
    }
}