@@ -20,110 +20,133 @@ fn main() {
2020}
2121
2222fn 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
6281fn 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
6988fn 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(
164187mod 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