json_diff/
lib.rs

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}