list.rs

 1use anyhow::Result;
 2use std::path::Path;
 3
 4use crate::db;
 5
 6pub fn run(
 7    root: &Path,
 8    status: Option<&str>,
 9    priority: Option<i32>,
10    label: Option<&str>,
11    json: bool,
12) -> Result<()> {
13    let conn = db::open(root)?;
14
15    let mut sql = String::from(
16        "SELECT id, title, description, type, priority, status, parent, created, updated
17         FROM tasks WHERE 1=1",
18    );
19    let mut params: Vec<Box<dyn rusqlite::types::ToSql>> = Vec::new();
20    let mut idx = 1;
21
22    if let Some(s) = status {
23        sql.push_str(&format!(" AND status = ?{idx}"));
24        params.push(Box::new(s.to_string()));
25        idx += 1;
26    }
27    if let Some(p) = priority {
28        sql.push_str(&format!(" AND priority = ?{idx}"));
29        params.push(Box::new(p));
30        idx += 1;
31    }
32    if let Some(l) = label {
33        sql.push_str(&format!(
34            " AND id IN (SELECT task_id FROM labels WHERE label = ?{idx})"
35        ));
36        params.push(Box::new(l.to_string()));
37    }
38
39    sql.push_str(" ORDER BY priority, created");
40
41    let param_refs: Vec<&dyn rusqlite::types::ToSql> = params.iter().map(|p| p.as_ref()).collect();
42    let mut stmt = conn.prepare(&sql)?;
43    let tasks: Vec<db::Task> = stmt
44        .query_map(param_refs.as_slice(), db::row_to_task)?
45        .collect::<rusqlite::Result<_>>()?;
46
47    if json {
48        let details: Vec<db::TaskDetail> = tasks
49            .into_iter()
50            .map(|t| {
51                let labels = db::load_labels(&conn, &t.id)?;
52                let blockers = db::load_blockers(&conn, &t.id)?;
53                Ok(db::TaskDetail {
54                    task: t,
55                    labels,
56                    blockers,
57                })
58            })
59            .collect::<Result<_>>()?;
60        println!("{}", serde_json::to_string(&details)?);
61    } else {
62        let c = crate::color::stdout_theme();
63        for t in &tasks {
64            println!(
65                "{}{:<12}{} {}{:<12}{} {}{:<4}{} {}",
66                c.bold,
67                t.id,
68                c.reset,
69                c.yellow,
70                format!("[{}]", t.status),
71                c.reset,
72                c.red,
73                format!("P{}", t.priority),
74                c.reset,
75                t.title,
76            );
77        }
78    }
79
80    Ok(())
81}