1use anyhow::{anyhow, Result};
2use std::collections::BTreeSet;
3use std::path::Path;
4
5use crate::cli::LabelAction;
6use crate::db;
7use crate::ops;
8
9pub fn run(root: &Path, action: &LabelAction, json: bool) -> Result<()> {
10 let store = db::open(root)?;
11
12 match action {
13 LabelAction::Add { id, label } => {
14 let task_id = db::resolve_task_id(&store, id, false)?;
15 ops::add_label(&store, &task_id, label)?;
16
17 if json {
18 println!("{}", serde_json::json!({"id": task_id, "label": label}));
19 } else {
20 let c = crate::color::stdout_theme();
21 println!("{}added{} label {label}", c.green, c.reset);
22 }
23 }
24 LabelAction::Rm { id, label } => {
25 let task_id = db::resolve_task_id(&store, id, false)?;
26 ops::remove_label(&store, &task_id, label)?;
27
28 if !json {
29 let c = crate::color::stdout_theme();
30 println!("{}removed{} label {label}", c.green, c.reset);
31 }
32 }
33 LabelAction::List { id } => {
34 let task_id = db::resolve_task_id(&store, id, false)?;
35 let task = store
36 .get_task(&task_id, false)?
37 .ok_or_else(|| anyhow!("task not found"))?;
38 if json {
39 println!("{}", serde_json::to_string(&task.labels)?);
40 } else {
41 for l in &task.labels {
42 println!("{l}");
43 }
44 }
45 }
46 LabelAction::ListAll => {
47 let mut set = BTreeSet::new();
48 for task in store.list_tasks()? {
49 for label in task.labels {
50 set.insert(label);
51 }
52 }
53 let labels: Vec<_> = set.into_iter().collect();
54 if json {
55 println!("{}", serde_json::to_string(&labels)?);
56 } else {
57 for l in &labels {
58 println!("{l}");
59 }
60 }
61 }
62 }
63
64 Ok(())
65}