can json diff

This commit is contained in:
bel
2025-11-10 23:20:01 -07:00
parent 56d5f59daf
commit 4067bd75fe
3 changed files with 90 additions and 64 deletions

89
pttodoest/src/main.rs Normal file → Executable file
View File

@@ -1,6 +1,7 @@
use clap::Parser;
use serde_yaml;
use std::io::Read;
use std::io::{Read, Write};
use serde::{Serialize, Deserialize};
fn main() {
for file in Flags::new()
@@ -100,27 +101,16 @@ impl File {
}
fn reconcile_snapshot_changes(&self) -> Result<(), String> {
let history = self.events()?.snapshot()?;
let cached = self.snapshot()?;
match history == cached {
true => Ok(()),
false => {
for task in history.iter() {
if !cached.contains(task) {
self.pop(task.clone())?;
}
}
for i in 0..cached.len() {
if !history.contains(&cached[i]) {
self.push(TaskAt {
task: cached[i].clone(),
at: i,
})?;
}
}
panic!("not impl")
}
}
let snapshot = self.events()?.snapshot()?;
let snapshot = serde_json::to_string(&snapshot).unwrap();
let snapshot: serde_json::Value = serde_json::from_str(snapshot.as_str()).unwrap();
let stage = self.snapshot()?;
let stage = serde_json::to_string(&stage).unwrap();
let stage: serde_json::Value = serde_json::from_str(stage.as_str()).unwrap();
let patch = json_patch::diff(&snapshot, &stage);
panic!("not impl jsondiff snapshots: {:?}", patch)
}
fn snapshot(&self) -> Result<Vec<Task>, String> {
@@ -147,47 +137,36 @@ impl File {
Ok(result)
}
fn push(&self, task_at: TaskAt) -> Result<(), String> {
self.append(Delta {
pushed_at: vec![task_at],
popped: vec![],
})
}
fn pop(&self, task: Task) -> Result<(), String> {
self.append(Delta {
pushed_at: vec![],
popped: vec![task],
})
}
fn append(&self, delta: Delta) -> Result<(), String> {
use std::fs::OpenOptions;
let hostname = gethostname::gethostname();
let mut file = match OpenOptions::new().write(true).append(true).open(&self.file) {
let log = format!("{}{}", Events::log_prefix(&self.file), gethostname::gethostname().into_string().unwrap());
let mut file = match OpenOptions::new().write(true).append(true).open(&log) {
Ok(f) => Ok(f),
Err(msg) => Err(format!(
"failed to open {} for appending: {}",
&self.file, msg
)),
}?;
panic!("not impl: {:?}", file)
let line = serde_json::to_string(&delta).unwrap();
match
writeln!(file, "{}", line) {
Ok(_) => Ok(()),
Err(msg) => Err(format!("failed to append: {}", msg)),
}
}
}
#[derive(Debug, Clone)]
struct Delta {
pushed_at: Vec<TaskAt>,
popped: Vec<Task>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
struct Delta(json_patch::Patch);
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Serialize, Deserialize)]
struct TaskAt {
task: Task,
at: usize,
}
#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
struct Task(serde_yaml::Value);
#[derive(Debug, Clone)]
@@ -238,25 +217,7 @@ impl Events {
fn snapshot(&self) -> Result<Vec<Task>, String> {
let mut result = vec![];
for event in self.0.iter() {
for popped in event.popped.iter() {
for i in (0..result.len())
.map(|i| i as usize)
.filter(|i| result[*i] == *popped)
{
panic!("not impl")
}
}
for push in event.pushed_at.iter() {
result.insert(
if push.at < result.len() {
push.at
} else {
result.len()
},
push.task.clone(),
);
}
panic!("not impl: {:?}", result)
panic!("not impl: {:?}", event)
}
Ok(result)
}