diff --git a/pttodoer/src/main.rs b/pttodoer/src/main.rs index 0d3029a..986e755 100644 --- a/pttodoer/src/main.rs +++ b/pttodoer/src/main.rs @@ -26,9 +26,8 @@ fn main() { }; if flags.edit { - db.edit().expect("failed to edit"); + db = db.edit().expect("failed to edit") } - db.save(flags.dry_run).expect("failed to save"); } @@ -115,7 +114,7 @@ impl DB { result } - pub fn edit(&self) -> Result<(), String> { + pub fn edit(&self) -> Result { let d = TempDir::new(&TS::now().to_string()).expect("failed to create a temp dir"); for set in &self.0 { let base = set.file.split("/").last().unwrap().to_string(); @@ -123,37 +122,62 @@ impl DB { set.save_due_as(f.display().to_string())?; } - //std::process::Command::new("/bin/sh") - // .current_dir(d.path()) - // .arg("-c") - // .arg("vim -p ./*") - // .spawn() - // .expect("failed to start vim") - // .wait() - // .expect("failed to vim"); + loop { + std::process::Command::new("/bin/sh") + .current_dir(d.path()) + .arg("-c") + .arg("vim -p ./*") + .spawn() + .expect("failed to start vim") + .wait() + .expect("failed to vim"); + let mut ok = true; + for set in &self.0 { + let base = set.file.split("/").last().unwrap().to_string(); + let f = d.path().join(base); + ok = ok && TasksAndMetadata::new(f.display().to_string()).is_ok(); + } + if ok { + break; + } + } + let mut result = vec![]; for set in &self.0 { let base = set.file.split("/").last().unwrap().to_string(); let f = d.path().join(base); - let edited = TasksAndMetadata::new(f.display().to_string()); - let not_due = set.not_due(); + let edited = TasksAndMetadata::new(f.display().to_string()).expect("failed to read edited tasks"); let was_due = set.due(); - // for each in was_due - // if not in edited - // not_due.push - // due = [] - // for each in edited - // if not due - // not_due.push - // else - // due.push - // all = due + not_due // ordered - // save to self.0 + let mut not_due = set.not_due(); + for task in &was_due.tasks.0 { + if !edited.tasks.0.contains(task) { + not_due.tasks.0.push(task.clone()); + } + } + + let mut now_due = vec![]; + for task in &edited.tasks.0 { + if task.is_due() { + now_due.push(task.clone()); + } else { + not_due.tasks.0.push(task.clone()); + } + } + + let mut new_tasks = Tasks::new(); + new_tasks.0.extend(now_due); + new_tasks.0.extend(not_due.tasks.0); + + result.push(TasksAndMetadata::new_with( + set.file.clone(), + set.version.clone(), + new_tasks, + )); } - Err("not impl".to_string()) + Ok(DB{0: result}) } pub fn save(&self, dry_run: bool) -> Result<(), String> { @@ -201,6 +225,14 @@ pub struct TasksAndMetadata { } impl TasksAndMetadata { + pub fn new_with(file: String, version: TS, tasks: Tasks) -> TasksAndMetadata { + TasksAndMetadata{ + file: file, + version: version, + tasks: tasks, + } + } + pub fn new(file: String) -> Result { let version = file_version(file.clone())?; match Tasks::from_file(file.clone()) { @@ -460,7 +492,7 @@ mod test_tasks { } -#[derive(Debug, serde::Serialize, serde::Deserialize, Clone)] +#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, PartialEq)] pub struct Task(serde_yaml::Mapping); impl Task { @@ -900,7 +932,7 @@ mod test_duration { } #[derive(Debug, PartialEq, Clone)] -struct TS(u64); +pub struct TS(u64); impl TS { fn now() -> TS {