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}