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