1pub mod constants;
2pub mod ds;
3mod process;
4use constants::Message;
5use ds::mismatch::Mismatch;
6
7pub fn compare_jsons(a: &str, b: &str) -> Result<Mismatch, Message> {
8 let value1 = match serde_json::from_str(a) {
9 Ok(val1) => val1,
10 Err(_) => return Err(Message::JSON1),
11 };
12 let value2 = match serde_json::from_str(b) {
13 Ok(val2) => val2,
14 Err(_) => return Err(Message::JSON2),
15 };
16 Ok(process::match_json(&value1, &value2))
17}
18
19#[cfg(test)]
20mod tests {
21 use super::ds::{key_node::KeyNode, mismatch::Mismatch};
22 use super::*;
23 use maplit::hashmap;
24 use serde_json::json;
25
26 #[test]
27 fn nested_diff() {
28 let data1 = r#"{
29 "a":"b",
30 "b":{
31 "c":{
32 "d":true,
33 "e":5,
34 "f":9,
35 "h":{
36 "i":true,
37 "j":false
38 }
39 }
40 }
41 }"#;
42 let data2 = r#"{
43 "a":"b",
44 "b":{
45 "c":{
46 "d":true,
47 "e":6,
48 "g":0,
49 "h":{
50 "i":false,
51 "k":false
52 }
53 }
54 }
55 }"#;
56
57 let expected_left = KeyNode::Node(hashmap! {
58 "b".to_string() => KeyNode::Node(hashmap! {
59 "c".to_string() => KeyNode::Node(hashmap! {
60 "f".to_string() => KeyNode::Nil,
61 "h".to_string() => KeyNode::Node( hashmap! {
62 "j".to_string() => KeyNode::Nil,
63 }
64 ),
65 }
66 ),
67 }),
68 });
69 let expected_right = KeyNode::Node(hashmap! {
70 "b".to_string() => KeyNode::Node(hashmap! {
71 "c".to_string() => KeyNode::Node(hashmap! {
72 "g".to_string() => KeyNode::Nil,
73 "h".to_string() => KeyNode::Node(hashmap! {
74 "k".to_string() => KeyNode::Nil,
75 }
76 )
77 }
78 )
79 }
80 )
81 });
82 let expected_uneq = KeyNode::Node(hashmap! {
83 "b".to_string() => KeyNode::Node(hashmap! {
84 "c".to_string() => KeyNode::Node(hashmap! {
85 "e".to_string() => KeyNode::Value(json!(5), json!(6)),
86 "h".to_string() => KeyNode::Node(hashmap! {
87 "i".to_string() => KeyNode::Value(json!(true), json!(false)),
88 }
89 )
90 }
91 )
92 }
93 )
94 });
95 let expected = Mismatch::new(expected_left, expected_right, expected_uneq);
96
97 let mismatch = compare_jsons(data1, data2).unwrap();
98 assert_eq!(mismatch, expected, "Diff was incorrect.");
99 }
100
101 #[test]
102 fn no_diff() {
103 let data1 = r#"{
104 "a":"b",
105 "b":{
106 "c":{
107 "d":true,
108 "e":5,
109 "f":9,
110 "h":{
111 "i":true,
112 "j":false
113 }
114 }
115 }
116 }"#;
117 let data2 = r#"{
118 "a":"b",
119 "b":{
120 "c":{
121 "d":true,
122 "e":5,
123 "f":9,
124 "h":{
125 "i":true,
126 "j":false
127 }
128 }
129 }
130 }"#;
131
132 assert_eq!(
133 compare_jsons(data1, data2).unwrap(),
134 Mismatch::new(KeyNode::Nil, KeyNode::Nil, KeyNode::Nil)
135 );
136 }
137
138 #[test]
139 fn no_json() {
140 let data1 = r#"{}"#;
141 let data2 = r#"{}"#;
142
143 assert_eq!(
144 compare_jsons(data1, data2).unwrap(),
145 Mismatch::new(KeyNode::Nil, KeyNode::Nil, KeyNode::Nil)
146 );
147 }
148
149 #[test]
150 fn parse_err_source_one() {
151 let invalid_json1 = r#"{invalid: json}"#;
152 let valid_json2 = r#"{"a":"b"}"#;
153 match compare_jsons(invalid_json1, valid_json2) {
154 Ok(_) => panic!("This shouldn't be an Ok"),
155 Err(err) => {
156 assert_eq!(Message::JSON1, err);
157 }
158 };
159 }
160
161 #[test]
162 fn parse_err_source_two() {
163 let valid_json1 = r#"{"a":"b"}"#;
164 let invalid_json2 = r#"{invalid: json}"#;
165 match compare_jsons(valid_json1, invalid_json2) {
166 Ok(_) => panic!("This shouldn't be an Ok"),
167 Err(err) => {
168 assert_eq!(Message::JSON2, err);
169 }
170 };
171 }
172}