1
+ mod constants;
2
+ mod ds;
3
+ mod process;
4
+
1
5
use colored:: * ;
6
+ use constants:: Message ;
7
+ use ds:: key_node:: KeyNode ;
8
+ use ds:: mismatch:: Mismatch ;
2
9
use serde_json;
3
- use serde_json:: Map ;
4
- use serde_json:: Value ;
5
- use std:: collections:: HashMap ;
6
- use std:: collections:: HashSet ;
7
10
use std:: fmt;
8
11
use std:: fs;
9
- use std:: process;
12
+ use std:: process as proc ;
10
13
use std:: str:: FromStr ;
11
14
use structopt:: StructOpt ;
12
- use constants:: Message ;
13
-
14
- mod constants;
15
15
16
16
const HELP : & str = r#"
17
17
Example:
@@ -59,7 +59,7 @@ struct Cli {
59
59
60
60
fn error_exit ( message : constants:: Message ) -> ! {
61
61
eprintln ! ( "{}" , message) ;
62
- process :: exit ( 1 ) ;
62
+ proc :: exit ( 1 ) ;
63
63
}
64
64
65
65
fn main ( ) {
@@ -130,64 +130,10 @@ fn display_output(result: Mismatch) {
130
130
}
131
131
}
132
132
133
- #[ derive( Debug , PartialEq ) ] // TODO check: do we need PartiaEq ?
134
- enum KeyNode {
135
- Nil ,
136
- Value ( Value , Value ) ,
137
- Node ( HashMap < String , KeyNode > ) ,
138
- }
139
-
140
- impl KeyNode {
141
- fn absolute_keys ( & self , keys : & mut Vec < String > , key_from_root : Option < String > ) {
142
- let val_key = |key : Option < String > | {
143
- key. map ( |mut s| {
144
- s. push_str ( " ->" ) ;
145
- s
146
- } )
147
- . unwrap_or ( String :: new ( ) )
148
- } ;
149
- let nil_key = |key : Option < String > | key. unwrap_or ( String :: new ( ) ) ;
150
- match self {
151
- KeyNode :: Nil => keys. push ( nil_key ( key_from_root) ) ,
152
- KeyNode :: Value ( a, b) => keys. push ( format ! (
153
- "{} [ {} :: {} ]" ,
154
- val_key( key_from_root) ,
155
- a. to_string( ) . blue( ) . bold( ) ,
156
- b. to_string( ) . cyan( ) . bold( )
157
- ) ) ,
158
- KeyNode :: Node ( map) => {
159
- for ( key, value) in map {
160
- value. absolute_keys (
161
- keys,
162
- Some ( format ! ( "{} {}" , val_key( key_from_root. clone( ) ) , key) ) ,
163
- )
164
- }
165
- }
166
- }
167
- }
168
- }
169
-
170
- #[ derive( Debug , PartialEq ) ]
171
- struct Mismatch {
172
- left_only_keys : KeyNode ,
173
- right_only_keys : KeyNode ,
174
- keys_in_both : KeyNode ,
175
- }
176
-
177
- impl Mismatch {
178
- fn new ( l : KeyNode , r : KeyNode , u : KeyNode ) -> Mismatch {
179
- Mismatch {
180
- left_only_keys : l,
181
- right_only_keys : r,
182
- keys_in_both : u,
183
- }
184
- }
185
- }
186
-
187
133
fn compare_jsons ( a : & str , b : & str ) -> Mismatch {
188
134
if let Ok ( value1) = serde_json:: from_str ( a) {
189
135
if let Ok ( value2) = serde_json:: from_str ( b) {
190
- match_json ( & value1, & value2)
136
+ process :: match_json ( & value1, & value2)
191
137
} else {
192
138
error_exit ( Message :: JSON2 ) ;
193
139
}
@@ -196,104 +142,6 @@ fn compare_jsons(a: &str, b: &str) -> Mismatch {
196
142
}
197
143
}
198
144
199
- fn match_json ( value1 : & Value , value2 : & Value ) -> Mismatch {
200
- match ( value1, value2) {
201
- ( Value :: Object ( a) , Value :: Object ( b) ) => {
202
- let ( left_only_keys, right_only_keys, intersection_keys) = intersect_maps ( & a, & b) ;
203
-
204
- let mut unequal_keys = KeyNode :: Nil ;
205
- let mut left_only_keys = get_map_of_keys ( left_only_keys) ;
206
- let mut right_only_keys = get_map_of_keys ( right_only_keys) ;
207
-
208
- if let Some ( intersection_keys) = intersection_keys {
209
- for key in intersection_keys {
210
- let Mismatch {
211
- left_only_keys : l,
212
- right_only_keys : r,
213
- keys_in_both : u,
214
- } = match_json ( & a. get ( & key) . unwrap ( ) , & b. get ( & key) . unwrap ( ) ) ;
215
- left_only_keys = insert_child_key_map ( left_only_keys, l, & key) ;
216
- right_only_keys = insert_child_key_map ( right_only_keys, r, & key) ;
217
- unequal_keys = insert_child_key_map ( unequal_keys, u, & key) ;
218
- }
219
- }
220
- Mismatch :: new ( left_only_keys, right_only_keys, unequal_keys)
221
- }
222
- ( a, b) => {
223
- if a == b {
224
- Mismatch :: new ( KeyNode :: Nil , KeyNode :: Nil , KeyNode :: Nil )
225
- } else {
226
- Mismatch :: new (
227
- KeyNode :: Nil ,
228
- KeyNode :: Nil ,
229
- KeyNode :: Value ( a. clone ( ) , b. clone ( ) ) ,
230
- )
231
- }
232
- }
233
- }
234
- }
235
-
236
- fn get_map_of_keys ( set : Option < HashSet < String > > ) -> KeyNode {
237
- if let Some ( set) = set {
238
- KeyNode :: Node (
239
- set. iter ( )
240
- . map ( |key| ( String :: from ( key) , KeyNode :: Nil ) )
241
- . collect ( ) ,
242
- )
243
- } else {
244
- KeyNode :: Nil
245
- }
246
- }
247
-
248
- fn insert_child_key_map ( parent : KeyNode , child : KeyNode , key : & String ) -> KeyNode {
249
- if child == KeyNode :: Nil {
250
- return parent;
251
- }
252
- if let KeyNode :: Node ( mut map) = parent {
253
- map. insert ( String :: from ( key) , child) ;
254
- KeyNode :: Node ( map) // This is weird! I just wanted to return back `parent` here
255
- } else if let KeyNode :: Nil = parent {
256
- let mut map = HashMap :: new ( ) ;
257
- map. insert ( String :: from ( key) , child) ;
258
- KeyNode :: Node ( map)
259
- } else {
260
- parent // TODO Trying to insert child node in a Value variant : Should not happen => Throw an error instead.
261
- }
262
- }
263
-
264
- fn intersect_maps (
265
- a : & Map < String , Value > ,
266
- b : & Map < String , Value > ,
267
- ) -> (
268
- Option < HashSet < String > > ,
269
- Option < HashSet < String > > ,
270
- Option < HashSet < String > > ,
271
- ) {
272
- let mut intersection = HashSet :: new ( ) ;
273
- let mut left = HashSet :: new ( ) ;
274
- let mut right = HashSet :: new ( ) ;
275
- for a_key in a. keys ( ) {
276
- if b. contains_key ( a_key) {
277
- intersection. insert ( String :: from ( a_key) ) ;
278
- } else {
279
- left. insert ( String :: from ( a_key) ) ;
280
- }
281
- }
282
- for b_key in b. keys ( ) {
283
- if !a. contains_key ( b_key) {
284
- right. insert ( String :: from ( b_key) ) ;
285
- }
286
- }
287
- let left = if left. len ( ) == 0 { None } else { Some ( left) } ;
288
- let right = if right. len ( ) == 0 { None } else { Some ( right) } ;
289
- let intersection = if intersection. len ( ) == 0 {
290
- None
291
- } else {
292
- Some ( intersection)
293
- } ;
294
- ( left, right, intersection)
295
- }
296
-
297
145
#[ cfg( test) ]
298
146
mod tests {
299
147
use super :: * ;
@@ -331,7 +179,6 @@ mod tests {
331
179
}
332
180
}"# ;
333
181
334
- let mismatch = compare_jsons ( data1, data2) ;
335
182
let expected_left = KeyNode :: Node ( hashmap ! {
336
183
"b" . to_string( ) => KeyNode :: Node ( hashmap! {
337
184
"c" . to_string( ) => KeyNode :: Node ( hashmap! {
@@ -371,6 +218,8 @@ mod tests {
371
218
)
372
219
} ) ;
373
220
let expected = Mismatch :: new ( expected_left, expected_right, expected_uneq) ;
221
+
222
+ let mismatch = compare_jsons ( data1, data2) ;
374
223
assert_eq ! ( mismatch, expected, "Diff was incorrect." ) ;
375
224
}
376
225
0 commit comments