faucet_cli/commands/
search.rs1use crate::cli::SearchArgs;
4use crate::error::{CliError, CliResult};
5use crate::registry_index::RegistryIndex;
6
7pub async fn run(args: SearchArgs) -> CliResult<()> {
9 let idx = RegistryIndex::load(args.index.as_deref())?;
10 let hits = idx.search(&args.term);
11
12 if args.json {
13 let out =
14 serde_json::to_string_pretty(&hits).map_err(|e| CliError::Config(e.to_string()))?;
15 println!("{out}");
16 return Ok(());
17 }
18
19 if hits.is_empty() {
20 println!("No connectors match '{}'.", args.term);
21 println!("Browse everything with `faucet list --available`.");
22 return Ok(());
23 }
24
25 println!("{} connector(s) matching '{}':\n", hits.len(), args.term);
26 for c in hits {
27 let badge = if c.verified { "verified" } else { "community" };
28 println!(
29 " {:<6} {:<14} {} [{badge}]",
30 c.kind, c.name, c.description
31 );
32 println!(
33 " crate {} · feature {}",
34 c.crate_name(),
35 c.feature_flag()
36 );
37 }
38 println!("\nInstall one with `faucet install <name> [--kind source|sink]`.");
39 Ok(())
40}
41
42#[cfg(test)]
43mod tests {
44 use super::*;
45 use crate::cli::SearchArgs;
46
47 #[tokio::test]
48 async fn search_runs_json_and_human() {
49 run(SearchArgs {
51 term: "kafka".into(),
52 index: None,
53 json: false,
54 })
55 .await
56 .unwrap();
57 run(SearchArgs {
59 term: "kafka".into(),
60 index: None,
61 json: true,
62 })
63 .await
64 .unwrap();
65 run(SearchArgs {
67 term: "zzz-nope".into(),
68 index: None,
69 json: false,
70 })
71 .await
72 .unwrap();
73 }
74}