Просмотр исходного кода

bin/tau-cli: add update subcommand (edit a task)

Dastan-glitch 4 лет назад
Родитель
Сommit
dad30e05b3
1 измененных файлов с 64 добавлено и 19 удалено
  1. 64 19
      bin/tau-cli/src/main.rs

+ 64 - 19
bin/tau-cli/src/main.rs

@@ -49,6 +49,13 @@ pub enum CliTauSubCommands {
         #[clap(short, long)]
         month: Option<String>,
     },
+    /// Update/Edit an existing task by ID
+    Update {
+        #[clap(short, long)]
+        id: Option<u64>,
+        #[clap(short, long)]
+        data: Option<String>,
+    },
 }
 
 /// Tau cli
@@ -63,6 +70,26 @@ pub struct CliTau {
     pub command: Option<CliTauSubCommands>,
 }
 
+fn due_as_timestamp(due: Option<String>) -> Option<i64> {
+    match due {
+        Some(du) => {
+            assert!(du.len() == 4);
+            let (day, month) = (du[..2].parse::<u32>().unwrap(), du[2..].parse::<u32>().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<Value> {
     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<i64>) -> Result<Value> {
     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<u64>, data: Value) -> Result<Value> {
+    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::<u32>()?, du[2..].parse::<u32>()?);
-                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<i64> = due_as_timestamp(Some(kv[1].trim().to_string()));
+                    json!({ kv[0]: parsed_data })
+                }
+                "rank" => {
+                    let parsed_data: Option<u64> = 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.");