Skip to main content

aperture_cli/cli/commands/
search.rs

1//! Handler for `aperture search`.
2
3use crate::config::manager::ConfigManager;
4use crate::constants;
5use crate::engine::loader;
6use crate::error::Error;
7use crate::fs::OsFileSystem;
8use crate::output::Output;
9use crate::search::{format_search_results, CommandSearcher};
10
11pub fn execute_search_command(
12    manager: &ConfigManager<OsFileSystem>,
13    query: &str,
14    api_filter: Option<&str>,
15    verbose: bool,
16    output: &Output,
17) -> Result<(), Error> {
18    let specs = manager.list_specs()?;
19    if specs.is_empty() {
20        output.info("No API specifications found. Use 'aperture config add' to register APIs.");
21        return Ok(());
22    }
23
24    let cache_dir = manager.config_dir().join(constants::DIR_CACHE);
25    let mut all_specs = std::collections::BTreeMap::new();
26    for spec_name in &specs {
27        if api_filter.is_some_and(|filter| spec_name != filter) {
28            continue;
29        }
30        match loader::load_cached_spec(&cache_dir, spec_name) {
31            Ok(spec) => {
32                all_specs.insert(spec_name.clone(), spec);
33            }
34            Err(e) => eprintln!("Warning: Could not load spec '{spec_name}': {e}"),
35        }
36    }
37
38    if all_specs.is_empty() {
39        match api_filter {
40            Some(filter) => {
41                output.info(format!("API '{filter}' not found or could not be loaded."));
42            }
43            None => output.info("No API specifications could be loaded."),
44        }
45        return Ok(());
46    }
47
48    let searcher = CommandSearcher::new();
49    let results = searcher.search(&all_specs, query, api_filter)?;
50    let formatted_results = format_search_results(&results, verbose);
51    for line in formatted_results {
52        // ast-grep-ignore: no-println
53        println!("{line}");
54    }
55    Ok(())
56}