can json diff
parent
56d5f59daf
commit
4067bd75fe
|
|
@ -164,6 +164,28 @@ version = "1.0.15"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
||||
|
||||
[[package]]
|
||||
name = "json-patch"
|
||||
version = "4.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f300e415e2134745ef75f04562dd0145405c2f7fd92065db029ac4b16b57fe90"
|
||||
dependencies = [
|
||||
"jsonptr",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jsonptr"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a5a3cc660ba5d72bce0b3bb295bf20847ccbb40fd423f3f05b61273672e561fe"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.177"
|
||||
|
|
@ -176,6 +198,12 @@ version = "0.11.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
|
||||
|
||||
[[package]]
|
||||
name = "once_cell_polyfill"
|
||||
version = "1.70.2"
|
||||
|
|
@ -197,7 +225,9 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"clap",
|
||||
"gethostname",
|
||||
"json-patch",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_yaml",
|
||||
]
|
||||
|
||||
|
|
@ -259,6 +289,19 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.145"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
"ryu",
|
||||
"serde",
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_yaml"
|
||||
version = "0.9.34+deprecated"
|
||||
|
|
@ -289,6 +332,26 @@ dependencies = [
|
|||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.22"
|
||||
|
|
|
|||
|
|
@ -6,5 +6,7 @@ edition = "2024"
|
|||
[dependencies]
|
||||
clap = { version = "4.5.51", features = ["derive"] }
|
||||
gethostname = "1.1.0"
|
||||
json-patch = "4.1.0"
|
||||
serde = { version = "1.0.228", features = ["serde_derive"] }
|
||||
serde_json = "1.0.145"
|
||||
serde_yaml = "0.9.34"
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue