Skip to content

Commit

Permalink
Fixing incorrect diffing for the whole document
Browse files Browse the repository at this point in the history
Closes #12
  • Loading branch information
idubrov committed Dec 9, 2022
1 parent 7631bae commit de6699d
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 10 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
@@ -0,0 +1,9 @@
# Changelog

## 0.28.0 (2022-12-09)

### Fixed

- Fixed incorrect diffing for the whole document. Previously, differ would incorrectly yield path of `"/"` when the
whole document is replaced. The correct path should be `""`. This is a breaking change.
[#18](https://github.com/idubrov/json-patch/pull/18)
34 changes: 24 additions & 10 deletions src/diff.rs
Expand Up @@ -9,7 +9,7 @@ struct PatchDiffer {
impl PatchDiffer {
fn new() -> Self {
Self {
path: "/".to_string(),
path: "".to_string(),
patch: super::Patch(Vec::new()),
shift: 0,
}
Expand All @@ -19,20 +19,15 @@ impl PatchDiffer {
impl<'a> treediff::Delegate<'a, treediff::value::Key, Value> for PatchDiffer {
fn push(&mut self, key: &treediff::value::Key) {
use std::fmt::Write;
if self.path.len() != 1 {
self.path.push('/');
}
self.path.push('/');
match *key {
treediff::value::Key::Index(idx) => write!(self.path, "{}", idx - self.shift).unwrap(),
treediff::value::Key::String(ref key) => append_path(&mut self.path, key),
}
}

fn pop(&mut self) {
let mut pos = self.path.rfind('/').unwrap_or(0);
if pos == 0 {
pos = 1;
}
let pos = self.path.rfind('/').unwrap_or(0);
self.path.truncate(pos);
self.shift = 0;
}
Expand Down Expand Up @@ -151,10 +146,29 @@ mod tests {
assert_eq!(
p,
serde_json::from_value(json!([
{ "op": "replace", "path": "/", "value": null },
{ "op": "replace", "path": "", "value": null },
]))
.unwrap()
);
let mut left = json!({"title": "Hello!"});
crate::patch(&mut left, &p).unwrap();
}

#[test]
pub fn diff_empty_key() {
let left = json!({"title": "Something", "": "Hello!"});
let right = json!({"title": "Something", "": "Bye!"});
let p = super::diff(&left, &right);
assert_eq!(
p,
serde_json::from_value(json!([
{ "op": "replace", "path": "/", "value": "Bye!" },
]))
.unwrap()
);
let mut left_patched = json!({"title": "Something", "": "Hello!"});
crate::patch(&mut left_patched, &p).unwrap();
assert_eq!(left_patched, right);
}

#[test]
Expand All @@ -164,7 +178,7 @@ mod tests {
assert_eq!(
p,
serde_json::from_value(json!([
{ "op": "replace", "path": "/", "value": { "title": "Hello!" } },
{ "op": "replace", "path": "", "value": { "title": "Hello!" } },
]))
.unwrap()
);
Expand Down

0 comments on commit de6699d

Please sign in to comment.