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

bin/tau-cli: clean up filter function

ghassmo 4 лет назад
Родитель
Сommit
058ca299a1
2 измененных файлов с 35 добавлено и 80 удалено
  1. 3 5
      bin/tau/tau-cli/src/main.rs
  2. 32 75
      bin/tau/tau-cli/src/util.rs

+ 3 - 5
bin/tau/tau-cli/src/main.rs

@@ -60,11 +60,9 @@ async fn start(options: CliTau) -> Result<()> {
 
                 let rank = rank.unwrap_or(0.0);
 
-                add(
-                        rpc_addr,
-                        json!([{"title": title, "desc": desc, "assign": assign, "project": project, "due": due, "rank": rank}]),
-                    )
-                        .await?;
+                add(rpc_addr,
+                    json!([{"title": title, "desc": desc, "assign": assign, "project": project, "due": due, "rank": rank}]),
+                    ).await?;
             }
 
             Some(CliTauSubCommands::Update { id, key, value }) => {

+ 32 - 75
bin/tau/tau-cli/src/util.rs

@@ -241,22 +241,21 @@ pub fn get_events(rep: Value) -> Result<String> {
 }
 
 pub fn timestamp_to_date(timestamp: Value, dt: &str) -> String {
-    let result = if timestamp.is_u64() {
-        let timestamp = timestamp.as_i64().unwrap();
-        match dt {
-            "date" => {
-                NaiveDateTime::from_timestamp(timestamp, 0).date().format("%A %-d %B").to_string()
-            }
-            "datetime" => {
-                NaiveDateTime::from_timestamp(timestamp, 0).format("%H:%M %A %-d %B").to_string()
-            }
-            _ => "".to_string(),
-        }
-    } else {
-        "".to_string()
-    };
+    let timestamp = timestamp.as_i64().unwrap_or(0);
+
+    if timestamp <= 0 {
+        return "".to_string()
+    }
 
-    result
+    match dt {
+        "date" => {
+            NaiveDateTime::from_timestamp(timestamp, 0).date().format("%A %-d %B").to_string()
+        }
+        "datetime" => {
+            NaiveDateTime::from_timestamp(timestamp, 0).format("%H:%M %A %-d %B").to_string()
+        }
+        _ => "".to_string(),
+    }
 }
 
 pub fn get_from_task(task: Value, value: &str) -> Result<String> {
@@ -271,53 +270,22 @@ pub fn get_from_task(task: Value, value: &str) -> Result<String> {
     Ok(result)
 }
 
-fn filter_tasks(tasks: Vec<Value>, filter: Option<String>) -> Result<Vec<Value>> {
-    let filter = match filter {
-        Some(f) => f,
-        None => "all".to_string(),
-    };
-
-    let filtered_tasks: Vec<Value> = match filter.as_str() {
-        "all" => tasks,
-
-        "open" => tasks
-            .into_iter()
-            .filter(|task| {
-                let events = match task["events"].as_array() {
-                    Some(t) => t.to_owned(),
-                    None => {
-                        error!("Value is not an array!");
-                        vec![]
-                    }
-                };
+// Helper function to check task's state
+fn check_task_state(task: &Value, state: &str) -> bool {
+    let mut default_events = serde_json::Map::new();
+    default_events.insert("action".into(), "open".into());
+    let default_events: Vec<Value> = vec![Value::from(default_events)];
 
-                let state = match events.last() {
-                    Some(s) => s["action"].as_str().unwrap(),
-                    None => "open",
-                };
-                state == "open"
-            })
-            .collect(),
-
-        "pause" => tasks
-            .into_iter()
-            .filter(|task| {
-                let events = match task["events"].as_array() {
-                    Some(t) => t.to_owned(),
-                    None => {
-                        error!("Value is not an array!");
-                        vec![]
-                    }
-                };
-
-                let state = match events.last() {
-                    Some(s) => s["action"].as_str().unwrap(),
-                    None => "open",
-                };
-                state == "pause"
-            })
-            .collect(),
+    let last_event = task["events"].as_array().unwrap_or(&default_events).last().unwrap();
+    let last_state = last_event["action"].as_str().unwrap();
+    state == last_state
+}
 
+fn apply_filter(tasks: Vec<Value>, filter: String) -> Result<Vec<Value>> {
+    let filtered_tasks: Vec<Value> = match filter.as_str() {
+        "open" => tasks.into_iter().filter(|task| check_task_state(task, "open")).collect(),
+        "pause" => tasks.into_iter().filter(|task| check_task_state(task, "pause")).collect(),
+        "stop" => tasks.into_iter().filter(|task| check_task_state(task, "stop")).collect(),
         "month" => tasks
             .into_iter()
             .filter(|task| {
@@ -331,22 +299,11 @@ fn filter_tasks(tasks: Vec<Value>, filter: Option<String>) -> Result<Vec<Value>>
         _ if filter.contains("assign:") | filter.contains("project:") => {
             let kv: Vec<&str> = filter.split(':').collect();
             let key = kv[0];
-            let value = kv[1];
+            let value = Value::from(kv[1]);
 
             tasks
                 .into_iter()
-                .filter(|task| {
-                    match task[key].as_array() {
-                        Some(t) => t.to_owned(),
-                        None => {
-                            error!("Value is not an array!");
-                            vec![]
-                        }
-                    }
-                    .iter()
-                    .map(|s| s.as_str().unwrap())
-                    .any(|x| x == value)
-                })
+                .filter(|task| task[key].as_array().unwrap_or(&vec![]).contains(&value))
                 .collect()
         }
 
@@ -386,8 +343,8 @@ pub fn list_tasks(rep: Value, filters: Vec<String>) -> Result<()> {
     let mut tasks: Vec<Value> = serde_json::from_value(rep)?;
 
     for filter in filters {
-        let temp = tasks;
-        tasks = filter_tasks(temp, Some(filter))?;
+        // TODO need to use iterator or reference instead of copy
+        tasks = apply_filter(tasks, filter)?;
     }
 
     tasks.sort_by(|a, b| b["rank"].as_f64().partial_cmp(&a["rank"].as_f64()).unwrap());