systemprompt_cli/commands/core/content/
search.rs1use super::types::{SearchOutput, SearchResultRow};
2use crate::cli_settings::CliConfig;
3use crate::shared::CommandOutput;
4use anyhow::Result;
5use clap::Args;
6use systemprompt_content::{SearchFilters, SearchRequest, SearchService};
7use systemprompt_database::DbPool;
8use systemprompt_identifiers::CategoryId;
9
10use crate::context::CommandContext;
11
12#[derive(Debug, Args)]
13pub struct SearchArgs {
14 #[arg(help = "Search query")]
15 pub query: String,
16
17 #[arg(long, help = "Filter by source ID")]
18 pub source: Option<String>,
19
20 #[arg(long, help = "Filter by category ID")]
21 pub category: Option<String>,
22
23 #[arg(long, default_value = "20")]
24 pub limit: i64,
25}
26
27pub async fn execute(args: SearchArgs, ctx: &CommandContext) -> Result<CommandOutput> {
28 execute_with_pool(args, &ctx.db_pool().await?, &ctx.cli).await
29}
30
31pub async fn execute_with_pool(
32 args: SearchArgs,
33 pool: &DbPool,
34 _config: &CliConfig,
35) -> Result<CommandOutput> {
36 let service = SearchService::new(pool)?;
37
38 let filters = args.category.as_ref().map(|cat| SearchFilters {
39 category_id: Some(CategoryId::new(cat.clone())),
40 });
41
42 let request = SearchRequest {
43 query: args.query.clone(),
44 filters,
45 limit: Some(args.limit),
46 };
47
48 let response = service.search(&request).await?;
49
50 let results: Vec<SearchResultRow> = response
51 .results
52 .into_iter()
53 .filter(|r| {
54 args.source
55 .as_ref()
56 .is_none_or(|src| r.source_id.as_str() == src)
57 })
58 .map(|r| SearchResultRow {
59 id: r.id,
60 slug: r.slug,
61 title: r.title,
62 description: if r.description.is_empty() {
63 None
64 } else {
65 Some(r.description)
66 },
67 image: r.image,
68 source_id: r.source_id,
69 category_id: r.category_id,
70 })
71 .collect();
72
73 let total = results.len() as i64;
74
75 let output = SearchOutput {
76 results,
77 total,
78 query: args.query,
79 };
80
81 Ok(
82 CommandOutput::table_of(vec!["id", "title", "slug", "source_id"], &output.results)
83 .with_title("Search Results"),
84 )
85}