Skip to content

Commit 102911a

Browse files
committed
Refactor code to store and return mismatched values
1 parent dc1f0ef commit 102911a

File tree

1 file changed

+145
-132
lines changed

1 file changed

+145
-132
lines changed

src/main.rs

Lines changed: 145 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -20,110 +20,133 @@ fn main() {
2020
}
2121

2222
fn display_output(result: Mismatch) {
23-
match result {
24-
Mismatch::None => println!("No mismatch was found."),
25-
Mismatch::Values => println!("Mismatch at root."),
26-
Mismatch::Objects(None, None, None) => println!("No mismatch was found."),
27-
Mismatch::Objects(a, b, c) => {
28-
if let Some(left_keys) = a {
29-
println!(
30-
"Following keys were not found in second object: {:?}",
31-
left_keys
32-
);
33-
}
34-
if let Some(right_keys) = b {
35-
println!(
36-
"Following keys were not found in first object: {:?}",
37-
right_keys
38-
);
39-
}
40-
if let Some(unequal_keys) = c {
41-
println!(
42-
"Following keys were not found to be equal: {:?}",
43-
unequal_keys
44-
);
23+
let no_mismatch = Mismatch {
24+
left_only_keys: KeyNode::Nil,
25+
right_only_keys: KeyNode::Nil,
26+
keys_in_both: KeyNode::Nil,
27+
};
28+
if no_mismatch == result {
29+
println!("No mismatch was found.");
30+
} else {
31+
match result.left_only_keys {
32+
KeyNode::Node(_) => println!(
33+
"Following keys are not found in second object: {:?}",
34+
result.left_only_keys
35+
),
36+
KeyNode::Value(_, _) => (), // TODO left_only_keys should never be Value type => Throw an error
37+
KeyNode::Nil => (),
38+
}
39+
match result.right_only_keys {
40+
KeyNode::Node(_) => println!(
41+
"Following keys are not found in first object: {:?}",
42+
result.right_only_keys
43+
),
44+
KeyNode::Value(_, _) => (), // TODO right_only_keys should never be Value type => Throw an error
45+
KeyNode::Nil => (),
46+
}
47+
match result.keys_in_both {
48+
KeyNode::Node(_) => {
49+
println!("Following values are not equal: {:?}", result.keys_in_both)
4550
}
51+
KeyNode::Value(_, _) => println!("Mismatch at root."),
52+
KeyNode::Nil => (),
4653
}
47-
};
54+
}
4855
}
4956

50-
#[derive(Debug, PartialEq)]
51-
struct KeyMap {
52-
keys: HashMap<String, Option<KeyMap>>,
57+
#[derive(Debug, PartialEq)] // TODO check: do we need PartiaEq ?
58+
enum KeyNode {
59+
Nil,
60+
Value(Value, Value),
61+
Node(HashMap<String, KeyNode>),
5362
}
5463

5564
#[derive(Debug, PartialEq)]
56-
enum Mismatch {
57-
None,
58-
Values,
59-
Objects(Option<KeyMap>, Option<KeyMap>, Option<KeyMap>),
65+
struct Mismatch {
66+
left_only_keys: KeyNode,
67+
right_only_keys: KeyNode,
68+
keys_in_both: KeyNode,
69+
}
70+
71+
impl Mismatch {
72+
fn new(l: KeyNode, r: KeyNode, u: KeyNode) -> Mismatch {
73+
Mismatch {
74+
left_only_keys: l,
75+
right_only_keys: r,
76+
keys_in_both: u,
77+
}
78+
}
6079
}
6180

6281
fn compare_jsons(a: &str, b: &str) -> Mismatch {
63-
let value: Value = serde_json::from_str(a).unwrap();
82+
let value1: Value = serde_json::from_str(a).unwrap();
6483
let value2: Value = serde_json::from_str(b).unwrap();
6584

66-
match_json(&value, &value2)
85+
match_json(&value1, &value2)
6786
}
6887

6988
fn match_json(value1: &Value, value2: &Value) -> Mismatch {
7089
match (value1, value2) {
7190
(Value::Object(a), Value::Object(b)) => {
7291
let (left_only_keys, right_only_keys, intersection_keys) = intersect_maps(&a, &b);
7392

74-
let mut unequal_keys = None;
93+
let mut unequal_keys = KeyNode::Nil;
7594
let mut left_only_keys = get_map_of_keys(left_only_keys);
7695
let mut right_only_keys = get_map_of_keys(right_only_keys);
7796

7897
if let Some(intersection_keys) = intersection_keys {
7998
for key in intersection_keys {
80-
match match_json(&a.get(&key).unwrap(), &b.get(&key).unwrap()) {
81-
Mismatch::Values => {
82-
unequal_keys.get_or_insert(KeyMap {
83-
keys: HashMap::new(),
84-
})
85-
.keys
86-
.insert(String::from(&key), None);
87-
},
88-
89-
Mismatch::Objects(left_keys, right_keys, mismatch_keys) => {
90-
insert_child_key_map(&mut left_only_keys, left_keys, &key);
91-
insert_child_key_map(&mut right_only_keys, right_keys, &key);
92-
insert_child_key_map(&mut unequal_keys, mismatch_keys, &key);
93-
},
94-
95-
Mismatch::None => (),
96-
}
99+
let Mismatch {
100+
left_only_keys: l,
101+
right_only_keys: r,
102+
keys_in_both: u,
103+
} = match_json(&a.get(&key).unwrap(), &b.get(&key).unwrap());
104+
left_only_keys = insert_child_key_map(left_only_keys, l, &key);
105+
right_only_keys = insert_child_key_map(right_only_keys, r, &key);
106+
unequal_keys = insert_child_key_map(unequal_keys, u, &key);
97107
}
98108
}
99-
Mismatch::Objects(left_only_keys, right_only_keys, unequal_keys)
109+
Mismatch::new(left_only_keys, right_only_keys, unequal_keys)
100110
}
101111
(a, b) => {
102112
if a == b {
103-
Mismatch::None
113+
Mismatch::new(KeyNode::Nil, KeyNode::Nil, KeyNode::Nil)
104114
} else {
105-
Mismatch::Values
115+
Mismatch::new(
116+
KeyNode::Nil,
117+
KeyNode::Nil,
118+
KeyNode::Value(a.clone(), b.clone()),
119+
)
106120
}
107121
}
108122
}
109123
}
110124

111-
fn get_map_of_keys(set: Option<HashSet<String>>) -> Option<KeyMap> {
112-
set.map(|s| KeyMap {
113-
keys: s
114-
.iter()
115-
.map(|key| (String::from(key), None))
116-
.collect(),
117-
})
125+
fn get_map_of_keys(set: Option<HashSet<String>>) -> KeyNode {
126+
if let Some(set) = set {
127+
KeyNode::Node(
128+
set.iter()
129+
.map(|key| (String::from(key), KeyNode::Nil))
130+
.collect(),
131+
)
132+
} else {
133+
KeyNode::Nil
134+
}
118135
}
119136

120-
fn insert_child_key_map(parent: &mut Option<KeyMap>, child: Option<KeyMap>, key: &String) {
121-
if child.is_some() {
122-
parent.get_or_insert(KeyMap {
123-
keys: HashMap::new(),
124-
})
125-
.keys
126-
.insert(String::from(key), child); // TODO check: do we ever insert 'None' here?
137+
fn insert_child_key_map(parent: KeyNode, child: KeyNode, key: &String) -> KeyNode {
138+
if child == KeyNode::Nil {
139+
return parent;
140+
}
141+
if let KeyNode::Node(mut map) = parent {
142+
map.insert(String::from(key), child);
143+
KeyNode::Node(map) // This is weird! I just wanted to return back `parent` here
144+
} else if let KeyNode::Nil = parent {
145+
let mut map = HashMap::new();
146+
map.insert(String::from(key), child);
147+
KeyNode::Node(map)
148+
} else {
149+
parent // TODO Trying to insert child node in a Value variant : Should not happen => Throw an error instead.
127150
}
128151
}
129152

@@ -164,6 +187,7 @@ fn intersect_maps(
164187
mod tests {
165188
use super::*;
166189
use maplit::hashmap;
190+
use serde_json::json;
167191

168192
#[test]
169193
fn nested_diff() {
@@ -197,71 +221,46 @@ mod tests {
197221
}"#;
198222

199223
let mismatch = compare_jsons(data1, data2);
200-
match mismatch {
201-
Mismatch::Objects(Some(a), Some(b), Some(c)) => {
202-
let expected_left = KeyMap {
203-
keys: hashmap! {
204-
"b".to_string() => Some(KeyMap {
205-
keys: hashmap! {
206-
"c".to_string() => Some(KeyMap {
207-
keys: hashmap! {
208-
"f".to_string() => None,
209-
"h".to_string() => Some(KeyMap {
210-
keys: hashmap! {
211-
"j".to_string() => None,
212-
}
213-
})
214-
}
215-
})
216-
}
217-
})
218-
},
219-
};
220-
221-
let expected_right = KeyMap {
222-
keys: hashmap! {
223-
"b".to_string() => Some(KeyMap {
224-
keys: hashmap! {
225-
"c".to_string() => Some(KeyMap {
226-
keys: hashmap! {
227-
"g".to_string() => None,
228-
"h".to_string() => Some(KeyMap {
229-
keys: hashmap! {
230-
"k".to_string() => None,
231-
}
232-
})
233-
}
234-
})
224+
let expected_left = KeyNode::Node(hashmap! {
225+
"b".to_string() => KeyNode::Node(hashmap! {
226+
"c".to_string() => KeyNode::Node(hashmap! {
227+
"f".to_string() => KeyNode::Nil,
228+
"h".to_string() => KeyNode::Node( hashmap! {
229+
"j".to_string() => KeyNode::Nil,
235230
}
236-
})
237-
},
238-
};
239-
240-
let expected_uneq = KeyMap {
241-
keys: hashmap! {
242-
"b".to_string() => Some(KeyMap {
243-
keys: hashmap! {
244-
"c".to_string() => Some(KeyMap {
245-
keys: hashmap! {
246-
"e".to_string() => None,
247-
"h".to_string() => Some(KeyMap {
248-
keys: hashmap! {
249-
"i".to_string() => None,
250-
}
251-
})
252-
}
253-
})
254-
}
255-
})
256-
},
257-
};
258-
259-
assert_eq!(a, expected_left, "Left was incorrect.");
260-
assert_eq!(b, expected_right, "Right was incorrect.");
261-
assert_eq!(c, expected_uneq, "unequals were incorrect.");
262-
}
263-
_ => assert!(false, "Mismatch was not of type Objects"),
264-
}
231+
),
232+
}
233+
),
234+
}),
235+
});
236+
let expected_right = KeyNode::Node(hashmap! {
237+
"b".to_string() => KeyNode::Node(hashmap! {
238+
"c".to_string() => KeyNode::Node(hashmap! {
239+
"g".to_string() => KeyNode::Nil,
240+
"h".to_string() => KeyNode::Node(hashmap! {
241+
"k".to_string() => KeyNode::Nil,
242+
}
243+
)
244+
}
245+
)
246+
}
247+
)
248+
});
249+
let expected_uneq = KeyNode::Node(hashmap! {
250+
"b".to_string() => KeyNode::Node(hashmap! {
251+
"c".to_string() => KeyNode::Node(hashmap! {
252+
"e".to_string() => KeyNode::Value(json!(5), json!(6)),
253+
"h".to_string() => KeyNode::Node(hashmap! {
254+
"i".to_string() => KeyNode::Value(json!(true), json!(false)),
255+
}
256+
)
257+
}
258+
)
259+
}
260+
)
261+
});
262+
let expected = Mismatch::new(expected_left, expected_right, expected_uneq);
263+
assert_eq!(mismatch, expected, "Diff was incorrect.");
265264
}
266265

267266
#[test]
@@ -295,6 +294,20 @@ mod tests {
295294
}
296295
}"#;
297296

298-
assert_eq!(compare_jsons(data1, data2), Mismatch::Objects(None, None, None));
297+
assert_eq!(
298+
compare_jsons(data1, data2),
299+
Mismatch::new(KeyNode::Nil, KeyNode::Nil, KeyNode::Nil)
300+
);
301+
}
302+
303+
#[test]
304+
fn no_json() {
305+
let data1 = r#"{}"#;
306+
let data2 = r#"{}"#;
307+
308+
assert_eq!(
309+
compare_jsons(data1, data2),
310+
Mismatch::new(KeyNode::Nil, KeyNode::Nil, KeyNode::Nil)
311+
);
299312
}
300313
}

0 commit comments

Comments
 (0)