update.rs

 1use anyhow::{anyhow, Result};
 2use std::path::Path;
 3
 4use crate::db;
 5
 6pub struct Opts<'a> {
 7    pub status: Option<&'a str>,
 8    pub priority: Option<db::Priority>,
 9    pub effort: Option<db::Effort>,
10    pub title: Option<&'a str>,
11    pub desc: Option<&'a str>,
12    pub json: bool,
13}
14
15pub fn run(root: &Path, id: &str, opts: Opts) -> Result<()> {
16    let store = db::open(root)?;
17    let task_id = db::resolve_task_id(&store, id, false)?;
18    let ts = db::now_utc();
19
20    let parsed_status = opts.status.map(db::parse_status).transpose()?;
21
22    store.apply_and_persist(|doc| {
23        let tasks = doc.get_map("tasks");
24        let task = db::get_task_map(&tasks, &task_id)?.ok_or_else(|| anyhow!("task not found"))?;
25
26        if let Some(s) = parsed_status {
27            task.insert("status", db::status_label(s))?;
28        }
29        if let Some(p) = opts.priority {
30            task.insert("priority", db::priority_label(p))?;
31        }
32        if let Some(e) = opts.effort {
33            task.insert("effort", db::effort_label(e))?;
34        }
35        if let Some(t) = opts.title {
36            task.insert("title", t)?;
37        }
38        if let Some(d) = opts.desc {
39            task.insert("description", d)?;
40        }
41        task.insert("updated_at", ts.clone())?;
42        Ok(())
43    })?;
44
45    if opts.json {
46        let task = store
47            .get_task(&task_id, false)?
48            .ok_or_else(|| anyhow!("task not found"))?;
49        println!("{}", serde_json::to_string(&task)?);
50    } else {
51        let c = crate::color::stdout_theme();
52        println!("{}updated{} {}", c.green, c.reset, task_id);
53    }
54
55    Ok(())
56}