ready.rs

 1use anyhow::Result;
 2use comfy_table::presets::NOTHING;
 3use comfy_table::Table;
 4use std::path::Path;
 5
 6use crate::db;
 7
 8pub fn run(root: &Path, json: bool) -> Result<()> {
 9    let conn = db::open(root)?;
10
11    let mut stmt = conn.prepare(
12        "SELECT id, title, description, type, priority, status, effort, parent, created, updated
13         FROM tasks
14         WHERE status = 'open'
15           AND id NOT IN (
16               SELECT b.task_id FROM blockers b
17               JOIN tasks t ON b.blocker_id = t.id
18               WHERE t.status != 'closed'
19           )
20         ORDER BY priority, created",
21    )?;
22
23    let tasks: Vec<db::Task> = stmt
24        .query_map([], db::row_to_task)?
25        .collect::<rusqlite::Result<_>>()?;
26
27    if json {
28        let summary: Vec<serde_json::Value> = tasks
29            .iter()
30            .map(|t| {
31                serde_json::json!({
32                    "id": t.id,
33                    "title": t.title,
34                    "priority": db::priority_label(t.priority),
35                    "effort": db::effort_label(t.effort),
36                })
37            })
38            .collect();
39        println!("{}", serde_json::to_string(&summary)?);
40    } else {
41        let c = crate::color::stdout_theme();
42        let mut table = Table::new();
43        table.load_preset(NOTHING);
44        table.set_header(vec!["ID", "PRIORITY", "EFFORT", "TITLE"]);
45        for t in &tasks {
46            table.add_row(vec![
47                format!("{}{}{}", c.green, t.id, c.reset),
48                format!("{}{}{}", c.red, db::priority_label(t.priority), c.reset),
49                format!("{}{}{}", c.blue, db::effort_label(t.effort), c.reset),
50                t.title.clone(),
51            ]);
52        }
53        if !tasks.is_empty() {
54            println!("{table}");
55        }
56    }
57
58    Ok(())
59}