Skip to content

Commit dc1f0ef

Browse files
committed
Refactoring
1 parent c520362 commit dc1f0ef

File tree

1 file changed

+95
-73
lines changed

1 file changed

+95
-73
lines changed

src/main.rs

Lines changed: 95 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -11,27 +11,20 @@ fn main() {
1111
let file1 = &args[1];
1212
let file2 = &args[2];
1313

14-
let data =
14+
let data1 =
1515
&fs::read_to_string(file1).expect(&format!("Error occurred while reading {}", file1));
1616
let data2 =
1717
&fs::read_to_string(file2).expect(&format!("Error occurred while reading {}", file2));
1818

19-
display_output(compare_jsons(data, data2));
20-
}
21-
22-
fn compare_jsons(a: &str, b: &str) -> Mismatch {
23-
let value: Value = serde_json::from_str(a).unwrap();
24-
let value2: Value = serde_json::from_str(b).unwrap();
25-
26-
match_json(&value, &value2)
19+
display_output(compare_jsons(data1, data2));
2720
}
2821

2922
fn display_output(result: Mismatch) {
3023
match result {
31-
Mismatch::NoMismatch => println!("No mismatch was found."),
32-
Mismatch::ValueMismatch => println!("Mismatch at root."),
33-
Mismatch::ObjectMismatch(None, None, None) => println!("No mismatch was found."),
34-
Mismatch::ObjectMismatch(a, b, c) => {
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) => {
3528
if let Some(left_keys) = a {
3629
println!(
3730
"Following keys were not found in second object: {:?}",
@@ -59,86 +52,81 @@ struct KeyMap {
5952
keys: HashMap<String, Option<KeyMap>>,
6053
}
6154

62-
#[derive(Debug)]
55+
#[derive(Debug, PartialEq)]
6356
enum Mismatch {
64-
NoMismatch,
65-
ValueMismatch,
66-
ObjectMismatch(Option<KeyMap>, Option<KeyMap>, Option<KeyMap>),
57+
None,
58+
Values,
59+
Objects(Option<KeyMap>, Option<KeyMap>, Option<KeyMap>),
6760
}
6861

69-
fn match_json(value: &Value, value1: &Value) -> Mismatch {
70-
match (value, value1) {
71-
(Value::Object(a), Value::Object(b)) => {
72-
let (left, right, intersection) = intersect_maps(&a, &b);
73-
let mut unequal_keys = None;
74-
75-
let mut left = left.map(|l| KeyMap {
76-
keys: l
77-
.iter()
78-
.map(|x| (String::from(x), None))
79-
.collect::<HashMap<String, Option<KeyMap>>>(),
80-
});
62+
fn compare_jsons(a: &str, b: &str) -> Mismatch {
63+
let value: Value = serde_json::from_str(a).unwrap();
64+
let value2: Value = serde_json::from_str(b).unwrap();
8165

82-
let mut right = right.map(|r| KeyMap {
83-
keys: r
84-
.iter()
85-
.map(|x| (String::from(x), None))
86-
.collect::<HashMap<String, Option<KeyMap>>>(),
87-
});
66+
match_json(&value, &value2)
67+
}
8868

89-
if let Some(intersection) = intersection {
90-
for key in intersection {
91-
if let Some((key, value)) =
92-
match match_json(&a.get(&key).unwrap(), &b.get(&key).unwrap()) {
93-
Mismatch::NoMismatch => None,
69+
fn match_json(value1: &Value, value2: &Value) -> Mismatch {
70+
match (value1, value2) {
71+
(Value::Object(a), Value::Object(b)) => {
72+
let (left_only_keys, right_only_keys, intersection_keys) = intersect_maps(&a, &b);
9473

95-
Mismatch::ValueMismatch => Some((key, None)),
74+
let mut unequal_keys = None;
75+
let mut left_only_keys = get_map_of_keys(left_only_keys);
76+
let mut right_only_keys = get_map_of_keys(right_only_keys);
9677

97-
Mismatch::ObjectMismatch(left_keys, right_keys, mismatch_keys) => {
98-
if let Some(left_keys) = left_keys {
99-
left.get_or_insert(KeyMap {
100-
keys: HashMap::new(),
101-
})
102-
.keys
103-
.insert(String::from(&key), Some(left_keys));
104-
}
105-
if let Some(right_keys) = right_keys {
106-
right
107-
.get_or_insert(KeyMap {
108-
keys: HashMap::new(),
109-
})
110-
.keys
111-
.insert(String::from(&key), Some(right_keys));
112-
}
113-
if let Some(mismatch_keys) = mismatch_keys {
114-
Some((String::from(&key), Some(mismatch_keys)))
115-
} else {
116-
None
117-
}
118-
}
119-
}
120-
{
121-
unequal_keys
122-
.get_or_insert(KeyMap {
78+
if let Some(intersection_keys) = intersection_keys {
79+
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 {
12383
keys: HashMap::new(),
12484
})
12585
.keys
126-
.insert(key, value);
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 => (),
12796
}
12897
}
12998
}
130-
Mismatch::ObjectMismatch(left, right, unequal_keys)
99+
Mismatch::Objects(left_only_keys, right_only_keys, unequal_keys)
131100
}
132101
(a, b) => {
133102
if a == b {
134-
Mismatch::NoMismatch
103+
Mismatch::None
135104
} else {
136-
Mismatch::ValueMismatch
105+
Mismatch::Values
137106
}
138107
}
139108
}
140109
}
141110

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+
})
118+
}
119+
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?
127+
}
128+
}
129+
142130
fn intersect_maps(
143131
a: &Map<String, Value>,
144132
b: &Map<String, Value>,
@@ -210,7 +198,7 @@ mod tests {
210198

211199
let mismatch = compare_jsons(data1, data2);
212200
match mismatch {
213-
Mismatch::ObjectMismatch(Some(a), Some(b), Some(c)) => {
201+
Mismatch::Objects(Some(a), Some(b), Some(c)) => {
214202
let expected_left = KeyMap {
215203
keys: hashmap! {
216204
"b".to_string() => Some(KeyMap {
@@ -272,7 +260,41 @@ mod tests {
272260
assert_eq!(b, expected_right, "Right was incorrect.");
273261
assert_eq!(c, expected_uneq, "unequals were incorrect.");
274262
}
275-
_ => assert!(false, "Mismatch was not of type ObjectMismatch"),
263+
_ => assert!(false, "Mismatch was not of type Objects"),
276264
}
277265
}
266+
267+
#[test]
268+
fn no_diff() {
269+
let data1 = r#"{
270+
"a":"b",
271+
"b":{
272+
"c":{
273+
"d":true,
274+
"e":5,
275+
"f":9,
276+
"h":{
277+
"i":true,
278+
"j":false
279+
}
280+
}
281+
}
282+
}"#;
283+
let data2 = r#"{
284+
"a":"b",
285+
"b":{
286+
"c":{
287+
"d":true,
288+
"e":5,
289+
"f":9,
290+
"h":{
291+
"i":true,
292+
"j":false
293+
}
294+
}
295+
}
296+
}"#;
297+
298+
assert_eq!(compare_jsons(data1, data2), Mismatch::Objects(None, None, None));
299+
}
278300
}

0 commit comments

Comments
 (0)