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 #[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}