From dc70c3ca7a22a8c5e414c68e9f50feaa5bc65229 Mon Sep 17 00:00:00 2001 From: Bel LaPointe <153096461+breel-render@users.noreply.github.com> Date: Tue, 11 Nov 2025 19:13:34 -0700 Subject: [PATCH] gettin closer --- pttodoest/src/main.rs | 88 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 72 insertions(+), 16 deletions(-) diff --git a/pttodoest/src/main.rs b/pttodoest/src/main.rs index 03ebf7f..c3b4af5 100755 --- a/pttodoest/src/main.rs +++ b/pttodoest/src/main.rs @@ -38,9 +38,13 @@ fn main() { } if flags.edit { - panic!( - "not impl: create tempfiles of now up-to-date-snapshots, diff vim'd, persist difs to logs, render logs" - ); + edit::files(&files); + for file in files.files.iter() { + file.persist_stage() + .expect("failed to persist edited stage to log file"); + file.stage_persisted() + .expect("failed to stage edits from log files"); + } } } @@ -76,13 +80,17 @@ impl Flags { } pub fn files(&self) -> Result { - let metadata = match std::fs::metadata(self.path.clone()) { + Self::files_with(&self.path) + } + + pub fn files_with(p: &String) -> Result { + let metadata = match std::fs::metadata(p.clone()) { Ok(v) => Ok(v), - Err(msg) => Err(format!("failed to load {}: {}", self.path.clone(), msg)), + Err(msg) => Err(format!("failed to load {}: {}", p.clone(), msg)), }?; let files = match metadata.is_dir() { - false => Ok(vec![self.path.clone()]), - true => match std::fs::read_dir(self.path.clone()) { + false => Ok(vec![p.clone()]), + true => match std::fs::read_dir(p.clone()) { Ok(paths) => Ok(paths .filter(|x| x.is_ok()) .map(|x| x.unwrap()) @@ -90,7 +98,7 @@ impl Flags { .map(|x| x.path().display().to_string()) .filter(|x| !x.contains("/.")) .collect()), - Err(msg) => Err(format!("failed to read {}: {}", self.path.clone(), msg)), + Err(msg) => Err(format!("failed to read {}: {}", p.clone(), msg)), }, }?; assert!(files.len() > 0, "no files"); @@ -159,15 +167,21 @@ impl File { pub fn persist_stage(&self) -> Result<(), String> { let persisted = self.events()?.snapshot()?; - let persisted = serde_json::to_string(&persisted).unwrap(); - let persisted = persisted.as_str(); - let persisted: serde_json::Value = serde_json::from_str(&persisted).unwrap(); let stage = self.stage()?; - let stage = serde_json::to_string(&stage).unwrap(); - let stage: serde_json::Value = serde_json::from_str(stage.as_str()).unwrap(); - let patches = json_patch::diff(&persisted, &stage); + self.persist_delta(persisted, stage) + } + + pub fn persist_delta(&self, before: Vec, after: Vec) -> Result<(), String> { + let before = serde_json::to_string(&before).unwrap(); + let before = before.as_str(); + let before: serde_json::Value = serde_json::from_str(&before).unwrap(); + + let after = serde_json::to_string(&after).unwrap(); + let after: serde_json::Value = serde_json::from_str(after.as_str()).unwrap(); + + let patches = json_patch::diff(&before, &after); let deltas: Vec = patches .iter() .map(|patch| patch.clone()) @@ -441,7 +455,7 @@ impl Events { .to_string() } - fn basename(file: &String) -> String { + pub fn basename(file: &String) -> String { let path = std::path::Path::new(&file); path.file_name() .expect("cannot get basename") @@ -561,7 +575,49 @@ mod tests { pub fn file_contains(d: &tempdir::TempDir, fname: &str, content: &str) { let p = d.path().join(&fname); - let file_content = std::fs::read_to_string(p).unwrap(); + let file_content = file_content(&p.to_str().unwrap().to_string()); assert!(file_content.contains(content)); } + + pub fn file_content(p: &String) -> String { + std::fs::read_to_string(p).unwrap() + } +} + +mod edit { + use super::*; + + pub fn files(files: &Files) { + tests::with_dir(|d| { + build_dir(&d, &files).expect("failed to build dir"); + edit_dir(&d).expect("failed to edit dir"); + persist_edits(&d, &files).expect("couldnt persist edited"); + }); + } + + fn build_dir(d: &tempdir::TempDir, files: &Files) -> Result<(), String> { + for file in files.files.iter() { + let content = tests::file_content(&file.file); + tests::write_file(d, Events::basename(&file.file).as_str(), content.as_str()); + } + Ok(()) + } + + fn edit_dir(d: &tempdir::TempDir) -> Result<(), String> { + panic!("not impl"); + } + + fn persist_edits(d: &tempdir::TempDir, files: &Files) -> Result<(), String> { + let new_files = Flags::files_with(&d.path().display().to_string())?; + assert_eq!(files.files.len(), new_files.files.len()); + + for i in 0..files.files.len() { + let file = &files.files[i]; + let before = file.stage()?; + let after = new_files.files[i].stage()?; + file.persist_delta(before, after)?; + } + + Ok(()) + } }