use clap::ArgMatches;
use crate::domain::model::search::SearchFilter;
use crate::domain::usecases::search::search_records;
use crate::infra::driven::fs::search_repository::NucleoSearchRepository;
use crate::infra::driving::cli::errors::{die1, CliError};
use crate::infra::driving::cli::theme;
use crate::infra::driving::cli::Context;
pub(in super::super) fn execute_search(matches: &ArgMatches, ctx: &Context<'_>) {
let query = crate::infra::driving::cli::helpers::required_str(matches, "query");
let mut filter = SearchFilter::new();
if let Some(kind) = matches.get_one::<String>("kind") {
filter = filter.kind(kind.as_str());
}
if let Some(limit_str) = matches.get_one::<String>("limit") {
if let Ok(n) = limit_str.parse::<usize>() {
filter = filter.limit(n);
}
}
let repo = NucleoSearchRepository {
issues_dir: ctx.issues_dir().to_path_buf(),
decision_kinds: ctx
.config()
.decision_kinds
.iter()
.map(|k| (k.kind.clone(), k.dir.clone()))
.collect(),
schema_version: ctx.config().schema_version,
};
let hits = search_records(&repo, query, &filter).unwrap_or_else(|e| {
die1(CliError::new(format!("search failed: {e}")), ctx.output_fmt);
});
if ctx.output_fmt.is_structured() {
crate::infra::driving::cli::render_structured(&hits, ctx.output_fmt);
return;
}
if hits.is_empty() {
println!("no results for {query:?}");
return;
}
for hit in &hits {
println!(
"{} {} {}",
theme::id(&hit.id.to_string()),
theme::label(hit.kind.as_str()),
hit.title.as_str(),
);
if let Some(excerpt) = &hit.excerpt {
println!(" {excerpt}");
}
}
}