diff --git a/bin/tau-cli/src/main.rs b/bin/tau-cli/src/main.rs index a55c8c793..2a4acc568 100644 --- a/bin/tau-cli/src/main.rs +++ b/bin/tau-cli/src/main.rs @@ -49,6 +49,13 @@ pub enum CliTauSubCommands { #[clap(short, long)] month: Option, }, + /// Update/Edit an existing task by ID + Update { + #[clap(short, long)] + id: Option, + #[clap(short, long)] + data: Option, + }, } /// Tau cli @@ -63,6 +70,26 @@ pub struct CliTau { pub command: Option, } +fn due_as_timestamp(due: Option) -> Option { + match due { + Some(du) => { + assert!(du.len() == 4); + let (day, month) = (du[..2].parse::().unwrap(), du[2..].parse::().unwrap()); + let mut year = Local::today().year(); + if month < Local::today().month() { + year += 1; + } + if month == Local::today().month() && day < Local::today().day() { + year += 1; + } + let dt = NaiveDate::from_ymd(year, month, day).and_hms(12, 0, 0); + + Some(dt.timestamp()) + } + None => None, + } +} + async fn request(r: jsonrpc::JsonRequest, url: String) -> Result { let reply: JsonResult = match jsonrpc::send_request(&Url::parse(&url)?, json!(r), None).await { Ok(v) => v, @@ -111,6 +138,14 @@ async fn list(url: &str, month: Option) -> Result { Ok(request(req, url.to_string()).await?) } +// Update task and returns `true` upon success. +// --> {"jsonrpc": "2.0", "method": "update", "params": [task_id, {"title": "new title"} ], "id": 1} +// <-- {"jsonrpc": "2.0", "result": true, "id": 1} +async fn update(url: &str, id: Option, data: Value) -> Result { + let req = jsonrpc::request(json!("update"), json!([id, data])); + Ok(request(req, url.to_string()).await?) +} + async fn start(options: CliTau) -> Result<()> { let rpc_addr = "tcp://127.0.0.1:8875"; match options.command { @@ -181,29 +216,12 @@ async fn start(options: CliTau) -> Result<()> { None }; - let d = if due.is_some() { - let du = due.unwrap(); - assert!(du.len() == 4); - let (day, month) = (du[..2].parse::()?, du[2..].parse::()?); - let mut year = Local::today().year(); - if month < Local::today().month() { - year += 1; - } - if month == Local::today().month() && day < Local::today().day() { - year += 1; - } - let dt = NaiveDate::from_ymd(year, month, day).and_hms(12, 0, 0); - // let dt_string = dt.format("%A %-d %B").to_string(); // Format: Weekday Day Month - let timestamp = dt.timestamp(); - Some(timestamp) - } else { - None - }; + let d = due_as_timestamp(due); let r = if rank.is_none() { Some(0) } else { rank }; add(rpc_addr, t.as_deref(), des.as_deref(), a, p, d, r).await?; - //println!("Added task: {:#?}", t); + return Ok(()) } Some(CliTauSubCommands::List { month }) => { @@ -266,6 +284,33 @@ async fn start(options: CliTau) -> Result<()> { return Ok(()) } + + Some(CliTauSubCommands::Update { id, data }) => { + let data = data.unwrap(); + let kv: Vec<&str> = data.as_str().split(':').collect(); + + let new_data = match kv[0] { + "title" | "description" => { + json!({kv[0]: kv[1].trim()}) + } + "due" => { + let parsed_data: Option = due_as_timestamp(Some(kv[1].trim().to_string())); + json!({ kv[0]: parsed_data }) + } + "rank" => { + let parsed_data: Option = Some(kv[1].trim().parse()?); + json!({ kv[0]: parsed_data }) + } + _ => { + let parsed_data: Vec<&str> = kv[1].trim().split(',').collect(); + json!({ kv[0]: parsed_data }) + } + }; + + update(rpc_addr, id, new_data).await?; + + return Ok(()) + } _ => (), } error!("Please run 'tau help' to see usage.");