Skip to main content

lux_cli/
search.rs

1use std::collections::HashMap;
2
3use clap::Args;
4use itertools::Itertools;
5use miette::{IntoDiagnostic, Result};
6use text_trees::{FormatCharacters, StringTreeNode, TreeFormatting};
7
8use lux_lib::{
9    config::Config,
10    package::{PackageName, PackageReq, PackageVersion},
11    remote_package_db::RemotePackageDB,
12};
13
14use crate::args::OutputFormat;
15
16#[derive(Args)]
17pub struct Search {
18    lua_package_req: PackageReq,
19    // TODO(vhyrro): Add options.
20    #[arg(long, default_value = "text", value_enum, ignore_case = true)]
21    output_format: OutputFormat,
22}
23
24pub async fn search(data: Search, config: Config) -> Result<()> {
25    let formatting = TreeFormatting::dir_tree(FormatCharacters::box_chars());
26
27    let package_db = RemotePackageDB::from_config(&config).await?;
28
29    let lua_package_req = data.lua_package_req;
30
31    let result = package_db.search(&lua_package_req);
32
33    match data.output_format {
34        OutputFormat::Json => {
35            let rock_to_version_map: HashMap<&PackageName, Vec<&PackageVersion>> =
36                HashMap::from_iter(result);
37            println!(
38                "{}",
39                serde_json::to_string(&rock_to_version_map).into_diagnostic()?
40            );
41        }
42        OutputFormat::Text => {
43            for (key, versions) in result.into_iter().sorted() {
44                let mut tree = StringTreeNode::new(key.to_string().to_owned());
45
46                for version in versions {
47                    tree.push(version.to_string());
48                }
49
50                println!(
51                    "{}",
52                    tree.to_string_with_format(&formatting).into_diagnostic()?
53                );
54            }
55        }
56    }
57
58    Ok(())
59}