search.rs

 1use anyhow::Result;
 2use comfy_table::presets::NOTHING;
 3use comfy_table::{Cell, Table};
 4use std::path::Path;
 5
 6use crate::color::{cell_bold, stdout_use_color};
 7use crate::db;
 8
 9pub fn run(root: &Path, query: &str, json: bool) -> Result<()> {
10    let conn = db::open(root)?;
11    let pattern = format!("%{query}%");
12
13    let mut stmt = conn.prepare(
14        "SELECT id, title, description, type, priority, status, effort, parent, created, updated
15         FROM tasks
16         WHERE title LIKE ?1 OR description LIKE ?1",
17    )?;
18
19    let tasks: Vec<db::Task> = stmt
20        .query_map([&pattern], db::row_to_task)?
21        .collect::<rusqlite::Result<_>>()?;
22
23    if json {
24        let summary: Vec<serde_json::Value> = tasks
25            .iter()
26            .map(|t| {
27                serde_json::json!({
28                    "id": t.id,
29                    "title": t.title,
30                    "status": t.status,
31                })
32            })
33            .collect();
34        println!("{}", serde_json::to_string(&summary)?);
35    } else {
36        let use_color = stdout_use_color();
37        let mut table = Table::new();
38        table.load_preset(NOTHING);
39        for t in &tasks {
40            table.add_row(vec![cell_bold(&t.id, use_color), Cell::new(&t.title)]);
41        }
42        if !tasks.is_empty() {
43            println!("{table}");
44        }
45    }
46
47    Ok(())
48}