faucet_cli/commands/
list.rs1use crate::cli::ListArgs;
7use crate::error::CliResult;
8use crate::registry::{sink_descriptions, sink_exists, source_descriptions, source_exists};
9use crate::registry_index::RegistryIndex;
10use crate::state::available_state_kinds;
11#[cfg(feature = "quality")]
12use crate::transforms::quality_descriptions;
13use crate::transforms::transform_descriptions;
14
15pub async fn run(args: ListArgs) -> CliResult<()> {
17 if args.available {
18 return list_available(args);
19 }
20 println!("Sources:");
21 print_two_column(&source_descriptions());
22 println!();
23 println!("Sinks:");
24 print_two_column(&sink_descriptions());
25 println!();
26 println!("Transforms:");
27 print_two_column(&transform_descriptions());
28 println!();
29 #[cfg(feature = "quality")]
30 {
31 println!("Quality checks:");
32 print_two_column(&quality_descriptions());
33 println!();
34 }
35 println!("State stores: {}", available_state_kinds().join(", "));
36 #[cfg(feature = "schedule")]
37 println!("Scheduler: compiled in (run `faucet schedule --help`, `faucet schema schedule`)");
38 Ok(())
39}
40
41fn list_available(args: ListArgs) -> CliResult<()> {
44 let idx = RegistryIndex::load(args.index.as_deref())?;
45 let mut connectors: Vec<_> = idx.connectors.iter().collect();
46 connectors.sort_by(|a, b| {
47 (a.kind.as_str(), a.name.as_str()).cmp(&(b.kind.as_str(), b.name.as_str()))
48 });
49 println!(
50 "Registry connectors ({} total). ● = compiled into this binary, ○ = available via `faucet install`:\n",
51 connectors.len()
52 );
53 for c in connectors {
54 let compiled = match c.kind.as_str() {
55 "source" => source_exists(&c.name),
56 "sink" => sink_exists(&c.name),
57 _ => false,
58 };
59 let mark = if compiled { '●' } else { '○' };
60 let badge = if c.verified { "verified" } else { "community" };
61 println!(
62 " {mark} {kind:<6} {name:<14} {desc} [{badge}]",
63 kind = c.kind,
64 name = c.name,
65 desc = c.description
66 );
67 }
68 Ok(())
69}
70
71fn print_two_column(entries: &[(&'static str, &'static str)]) {
72 if entries.is_empty() {
73 println!(" (none — rebuild faucet-cli with the relevant features enabled)");
74 return;
75 }
76 let width = entries.iter().map(|(n, _)| n.len()).max().unwrap_or(0);
77 for (name, desc) in entries {
78 println!(" {name:<width$} {desc}", width = width);
79 }
80}