1use anyhow::Result;
2use std::path::Path;
3
4use crate::cli::LabelAction;
5use crate::db;
6
7pub fn run(root: &Path, action: &LabelAction, json: bool) -> Result<()> {
8 let conn = db::open(root)?;
9
10 match action {
11 LabelAction::Add { id, label } => {
12 conn.execute(
13 "INSERT OR IGNORE INTO labels (task_id, label) VALUES (?1, ?2)",
14 [id, label],
15 )?;
16 conn.execute(
17 "UPDATE tasks SET updated = ?1 WHERE id = ?2",
18 rusqlite::params![db::now_utc(), id],
19 )?;
20 if json {
21 println!("{}", serde_json::json!({"id": id, "label": label}));
22 } else {
23 let c = crate::color::stdout_theme();
24 println!("{}added{} label {label}", c.green, c.reset);
25 }
26 }
27 LabelAction::Rm { id, label } => {
28 conn.execute(
29 "DELETE FROM labels WHERE task_id = ?1 AND label = ?2",
30 [id, label],
31 )?;
32 conn.execute(
33 "UPDATE tasks SET updated = ?1 WHERE id = ?2",
34 rusqlite::params![db::now_utc(), id],
35 )?;
36 if !json {
37 let c = crate::color::stdout_theme();
38 println!("{}removed{} label {label}", c.green, c.reset);
39 }
40 }
41 LabelAction::List { id } => {
42 let labels = db::load_labels(&conn, id)?;
43 if json {
44 println!("{}", serde_json::to_string(&labels)?);
45 } else {
46 for l in &labels {
47 println!("{l}");
48 }
49 }
50 }
51 LabelAction::ListAll => {
52 let mut stmt = conn.prepare("SELECT DISTINCT label FROM labels ORDER BY label")?;
53 let labels: Vec<String> = stmt
54 .query_map([], |r| r.get(0))?
55 .collect::<rusqlite::Result<_>>()?;
56 if json {
57 println!("{}", serde_json::to_string(&labels)?);
58 } else {
59 for l in &labels {
60 println!("{l}");
61 }
62 }
63 }
64 }
65
66 Ok(())
67}