Skip to content

Commit b346787

Browse files
committed
Fix struct-in-map diffing
1 parent f5c05cf commit b346787

File tree

3 files changed

+87
-3
lines changed

3 files changed

+87
-3
lines changed

Cargo.toml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
[package]
22
name = "serde-diff"
33
version = "0.4.1"
4-
authors = ["Karl Bergström <karl.anton.bergstrom@gmail.com>", "Philip Degarmo <aclysma@gmail.com>"]
4+
authors = [
5+
"Karl Bergström <karl.anton.bergstrom@gmail.com>",
6+
"Philip Degarmo <aclysma@gmail.com>",
7+
]
58
readme = "README.md"
69
exclude = ["examples/*"]
710
license = "Apache-2.0 OR MIT"
@@ -17,10 +20,11 @@ maintenance = { status = "experimental" }
1720

1821
[dependencies]
1922
serde-diff-derive = { version = "0.4.0", path = "serde-diff-derive" }
20-
serde = { version = "1", features = [ "derive" ] }
21-
serde_derive = { version = "1", features = ["deserialize_in_place"]}
23+
serde = { version = "1", features = ["derive"] }
24+
serde_derive = { version = "1", features = ["deserialize_in_place"] }
2225

2326
[dev-dependencies]
2427
serde_json = "1.0"
2528
bincode = "1.2"
2629
rmp-serde = "0.15.0"
30+
maplit = "1.0.2"

examples/nested_map.rs

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
use maplit::hashmap;
2+
use serde::{Deserialize, Serialize};
3+
use serde_diff::{Apply, Diff, SerdeDiff};
4+
use std::collections::HashMap;
5+
6+
#[derive(SerdeDiff, Serialize, Deserialize, Debug, Default, PartialEq, Clone)]
7+
struct TestValue {
8+
v: String,
9+
}
10+
11+
#[derive(SerdeDiff, Serialize, Deserialize, Debug, Default, PartialEq, Clone)]
12+
struct TestStruct {
13+
test: bool,
14+
map: HashMap<String, HashMap<i32, TestValue>>,
15+
}
16+
17+
fn main() -> Result<(), Box<dyn std::error::Error>> {
18+
let mut empty = TestStruct::default();
19+
empty.test = true;
20+
21+
let mut hello_world = TestStruct::default();
22+
hello_world.map.insert(
23+
"hello".to_string(),
24+
hashmap![0 => TestValue { v: "world".to_string()}],
25+
);
26+
27+
let mut hi_world = TestStruct::default();
28+
hi_world.map.insert(
29+
"hi".to_string(),
30+
hashmap![0 => TestValue { v: "world".to_string()}],
31+
);
32+
33+
let mut hi_world_and_planet = TestStruct::default();
34+
hi_world_and_planet.map.insert(
35+
"hi".to_string(),
36+
hashmap![0 => TestValue { v: "world".to_string()}, 1 => TestValue { v: "planet".to_string()}],
37+
);
38+
39+
let mut hi_planet = TestStruct::default();
40+
hi_planet.map.insert(
41+
"hi".to_string(),
42+
hashmap![0 => TestValue { v: "planet".to_string()}],
43+
);
44+
45+
let mut hi_planet_hello_world = TestStruct::default();
46+
hi_planet_hello_world.map.insert(
47+
"hi".to_string(),
48+
hashmap![0 => TestValue { v: "planet".to_string()}],
49+
);
50+
hi_planet_hello_world.map.insert(
51+
"hello".to_string(),
52+
hashmap![0 => TestValue { v: "world".to_string()}],
53+
);
54+
55+
let add_hello = serde_json::to_string(&Diff::serializable(&empty, &hello_world))?;
56+
let hello_to_hi = serde_json::to_string(&Diff::serializable(&hello_world, &hi_world))?;
57+
let add_planet = serde_json::to_string(&Diff::serializable(&hi_world, &hi_world_and_planet))?;
58+
let del_world = serde_json::to_string(&Diff::serializable(&hi_world_and_planet, &hi_planet))?;
59+
let no_change = serde_json::to_string(&Diff::serializable(&hi_planet, &hi_planet))?;
60+
let add_world = serde_json::to_string(&Diff::serializable(&hi_planet, &hi_planet_hello_world))?;
61+
62+
let mut built = TestStruct::default();
63+
for (diff, after) in &[
64+
(add_hello, hello_world),
65+
(hello_to_hi, hi_world),
66+
(add_planet, hi_world_and_planet),
67+
(del_world, hi_planet.clone()),
68+
(no_change, hi_planet),
69+
(add_world, hi_planet_hello_world),
70+
] {
71+
println!("{}", diff);
72+
73+
let mut deserializer = serde_json::Deserializer::from_str(&diff);
74+
Apply::apply(&mut deserializer, &mut built)?;
75+
76+
assert_eq!(after, &built);
77+
}
78+
Ok(())
79+
}

src/implementation.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ macro_rules! map_serde_diff {
172172
if <V as SerdeDiff>::diff(self_value, &mut subctx, other_value)? {
173173
changed = true;
174174
}
175+
subctx.pop_path_element()?;
175176
},
176177
None => {
177178
ctx.save_command(&DiffCommandRef::RemoveKey(key), true, true)?;

0 commit comments

Comments
 (0)