From 161eb95101f17ea2a859319c5a3e551e6454708e Mon Sep 17 00:00:00 2001 From: Dheepak Krishnamurthy Date: Sat, 30 Oct 2021 17:38:08 -0600 Subject: [PATCH] =?UTF-8?q?fix:=20Change=20parsing=20of=20task=20summary?= =?UTF-8?q?=20for=20project=20pane=20=F0=9F=90=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pane/project.rs | 90 ++++++++++++++++++++++++--------------------- 1 file changed, 48 insertions(+), 42 deletions(-) diff --git a/src/pane/project.rs b/src/pane/project.rs index df9e9f9..72d9168 100644 --- a/src/pane/project.rs +++ b/src/pane/project.rs @@ -40,12 +40,14 @@ pub struct ProjectsState { pub rows: Vec, } +#[derive(Debug, Clone, Default)] pub struct ProjectDetails { name: Project, remaining: usize, avg_age: String, complete: String, } + impl ProjectsState { pub(crate) fn new() -> Self { Self { @@ -118,50 +120,39 @@ impl ProjectsState { .context("Unable to run `task summary`") .unwrap(); let data = String::from_utf8_lossy(&output.stdout); - let contains_avg_age = data - .split('\n') - .into_iter() - .skip(1) - .collect::>() - .first() - .unwrap() - .contains("Avg age"); - for line in data.split('\n').into_iter().skip(3) { - if line.is_empty() { - break; - } - let mut row: Vec = line - .split(' ') - .map(str::trim) - .map(str::trim_start) - .filter(|x| !x.is_empty()) - .filter(|x| !x.chars().all(|c| c == '=')) - .map(ToString::to_string) - .collect(); - assert!(row.len() >= 3); - let (complete, avg_age, remaining, name) = if contains_avg_age { - ( - row.pop().unwrap().parse().unwrap(), - row.pop().unwrap().parse().unwrap(), - row.pop().unwrap().parse().unwrap(), - row.join(" "), - ) - } else { - ( - row.pop().unwrap().parse().unwrap(), - "0s".to_string(), - row.pop().unwrap().parse().unwrap(), - row.join(" "), - ) - }; - self.rows.push(ProjectDetails { - name, - remaining, - avg_age, - complete, - }); + let lines = data.split('\n').into_iter().skip(1).collect::>(); + + let header = lines.first().unwrap(); + + let contains_avg_age = header.contains("Avg age"); + + if contains_avg_age { + let name_index = header.find("Remaining").unwrap(); + let remaining_index = header.find("Remaining").unwrap() + "Remaining".len(); + let average_age_index = header.find("Avg age").unwrap() + "Avg age".len(); + let complete_index = header.find("Complete").unwrap() + "Complete".len(); + + for line in lines.into_iter().skip(2) { + if line.is_empty() { + break; + } + + let line = line.to_string(); + let name = line[0..name_index].trim().to_string(); + let remaining = line[name_index..remaining_index].trim().parse().unwrap(); + let avg_age = line[remaining_index..average_age_index].trim().to_string(); + let complete = line[average_age_index..complete_index].trim().to_string(); + + self.rows.push(ProjectDetails { + name, + remaining, + avg_age, + complete, + }); + } } + self.list = self.rows.iter().map(|x| x.name.clone()).collect_vec(); Ok(()) } @@ -229,3 +220,18 @@ fn update_task_filter_by_selection(app: &mut TaskwarriorTui) -> Result<()> { app.update(true)?; Ok(()) } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_project_summary() { + let mut app = TaskwarriorTui::new("next").unwrap(); + + app.update(true).unwrap(); + + dbg!(&app.projects.rows); + dbg!(&app.projects.list); + } +}