1 extern crate jsonpath_lib as jsonpath;
2 extern crate serde;
3 #[macro_use]
4 extern crate serde_json;
5 
6 use serde::Deserialize;
7 use serde_json::Value;
8 
9 use jsonpath::{Selector, SelectorMut};
10 
11 mod common;
12 
13 #[test]
readme()14 fn readme() {
15     let json_obj = json!({
16         "store": {
17             "book": [
18                 {
19                     "category": "reference",
20                     "author": "Nigel Rees",
21                     "title": "Sayings of the Century",
22                     "price": 8.95
23                 },
24                 {
25                     "category": "fiction",
26                     "author": "Evelyn Waugh",
27                     "title": "Sword of Honour",
28                     "price": 12.99
29                 },
30                 {
31                     "category": "fiction",
32                     "author": "Herman Melville",
33                     "title": "Moby Dick",
34                     "isbn": "0-553-21311-3",
35                     "price": 8.99
36                 },
37                 {
38                     "category": "fiction",
39                     "author": "J. R. R. Tolkien",
40                     "title": "The Lord of the Rings",
41                     "isbn": "0-395-19395-8",
42                     "price": 22.99
43                 }
44             ],
45             "bicycle": {
46                 "color": "red",
47                 "price": 19.95
48             }
49         },
50         "expensive": 10
51     });
52 
53     let mut selector = jsonpath::selector(&json_obj);
54 
55     assert_eq!(
56         selector("$.store.book[*].author").unwrap(),
57         vec![
58             "Nigel Rees",
59             "Evelyn Waugh",
60             "Herman Melville",
61             "J. R. R. Tolkien"
62         ]
63     );
64 
65     assert_eq!(
66         selector("$..author").unwrap(),
67         vec![
68             "Nigel Rees",
69             "Evelyn Waugh",
70             "Herman Melville",
71             "J. R. R. Tolkien"
72         ]
73     );
74 
75     assert_eq!(
76         selector("$.store.*").unwrap(),
77         vec![
78             &json!([
79                 { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95 },
80                 { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99 },
81                 { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99 },
82                 { "category": "fiction", "author": "J. R. R. Tolkien", "title": "The Lord of the Rings", "isbn": "0-395-19395-8", "price": 22.99 }
83             ]),
84             &json!({ "color": "red", "price": 19.95 })
85         ]
86     );
87 
88     assert_eq!(
89         selector("$.store..price").unwrap(),
90         vec![8.95, 12.99, 8.99, 22.99, 19.95]
91     );
92 
93     assert_eq!(
94         selector("$..book[2]").unwrap(),
95         vec![&json!({
96             "category" : "fiction",
97             "author" : "Herman Melville",
98             "title" : "Moby Dick",
99             "isbn" : "0-553-21311-3",
100             "price" : 8.99
101         })]
102     );
103 
104     assert_eq!(
105         selector("$..book[-2]").unwrap(),
106         vec![&json!({
107             "category" : "fiction",
108             "author" : "Herman Melville",
109             "title" : "Moby Dick",
110             "isbn" : "0-553-21311-3",
111             "price" : 8.99
112         })]
113     );
114 
115     assert_eq!(
116         selector("$..book[0,1]").unwrap(),
117         vec![
118             &json!({"category" : "reference","author" : "Nigel Rees","title" : "Sayings of the Century","price" : 8.95}),
119             &json!({"category" : "fiction","author" : "Evelyn Waugh","title" : "Sword of Honour","price" : 12.99})
120         ]
121     );
122 
123     assert_eq!(
124         selector("$..book[:2]").unwrap(),
125         vec![
126             &json!({"category" : "reference","author" : "Nigel Rees","title" : "Sayings of the Century","price" : 8.95}),
127             &json!({"category" : "fiction","author" : "Evelyn Waugh","title" : "Sword of Honour","price" : 12.99})
128         ]
129     );
130 
131     assert_eq!(
132         selector("$..book[:2]").unwrap(),
133         vec![
134             &json!({"category" : "reference","author" : "Nigel Rees","title" : "Sayings of the Century","price" : 8.95}),
135             &json!({"category" : "fiction","author" : "Evelyn Waugh","title" : "Sword of Honour","price" : 12.99})
136         ]
137     );
138 
139     assert_eq!(
140         selector("$..book[?(@.isbn)]").unwrap(),
141         vec![
142             &json!({"category" : "fiction","author" : "Herman Melville","title" : "Moby Dick","isbn" : "0-553-21311-3","price" : 8.99}),
143             &json!({"category" : "fiction","author" : "J. R. R. Tolkien","title" : "The Lord of the Rings","isbn" : "0-395-19395-8","price" : 22.99})
144         ]
145     );
146 
147     assert_eq!(
148         selector("$.store.book[?(@.price < 10)]").unwrap(),
149         vec![
150             &json!({"category" : "reference","author" : "Nigel Rees","title" : "Sayings of the Century","price" : 8.95}),
151             &json!({"category" : "fiction","author" : "Herman Melville","title" : "Moby Dick","isbn" : "0-553-21311-3","price" : 8.99})
152         ]
153     );
154 }
155 
156 #[test]
readme_selector()157 fn readme_selector() {
158     #[derive(Deserialize, PartialEq, Debug)]
159     struct Friend {
160         name: String,
161         age: Option<u8>,
162     }
163 
164     let json_obj = json!({
165         "school": {
166             "friends": [
167                 {"name": "친구1", "age": 20},
168                 {"name": "친구2", "age": 20}
169             ]
170         },
171         "friends": [
172             {"name": "친구3", "age": 30},
173             {"name": "친구4"}
174     ]});
175 
176     let mut selector = Selector::default();
177 
178     let result = selector
179         .str_path("$..[?(@.age >= 30)]")
180         .unwrap()
181         .value(&json_obj)
182         .select()
183         .unwrap();
184 
185     assert_eq!(vec![&json!({"name": "친구3", "age": 30})], result);
186 
187     let result = selector.select_as_str().unwrap();
188     assert_eq!(r#"[{"name":"친구3","age":30}]"#, result);
189 
190     let result = selector.select_as::<Friend>().unwrap();
191     assert_eq!(
192         vec![Friend {
193             name: "친구3".to_string(),
194             age: Some(30)
195         }],
196         result
197     );
198 }
199 
200 #[test]
readme_selector_mut()201 fn readme_selector_mut() {
202     let json_obj = json!({
203         "school": {
204             "friends": [
205                 {"name": "친구1", "age": 20},
206                 {"name": "친구2", "age": 20}
207             ]
208         },
209         "friends": [
210             {"name": "친구3", "age": 30},
211             {"name": "친구4"}
212     ]});
213 
214     let mut selector_mut = SelectorMut::default();
215 
216     let result = selector_mut
217         .str_path("$..[?(@.age == 20)].age")
218         .unwrap()
219         .value(json_obj)
220         .replace_with(&mut |v| {
221             let age = if let Value::Number(n) = v {
222                 n.as_u64().unwrap() * 2
223             } else {
224                 0
225             };
226 
227             Some(json!(age))
228         })
229         .unwrap()
230         .take()
231         .unwrap();
232 
233     assert_eq!(
234         result,
235         json!({
236             "school": {
237                 "friends": [
238                     {"name": "친구1", "age": 40},
239                     {"name": "친구2", "age": 40}
240                 ]
241             },
242             "friends": [
243                 {"name": "친구3", "age": 30},
244                 {"name": "친구4"}
245         ]})
246     );
247 }
248 
249 #[test]
readme_select()250 fn readme_select() {
251     let json_obj = json!({
252         "school": {
253             "friends": [
254                 {"name": "친구1", "age": 20},
255                 {"name": "친구2", "age": 20}
256             ]
257         },
258         "friends": [
259             {"name": "친구3", "age": 30},
260             {"name": "친구4"}
261     ]});
262 
263     let json = jsonpath::select(&json_obj, "$..friends[0]").unwrap();
264 
265     assert_eq!(
266         json,
267         vec![
268             &json!({"name": "친구3", "age": 30}),
269             &json!({"name": "친구1", "age": 20})
270         ]
271     );
272 }
273 
274 #[test]
readme_select_as_str()275 fn readme_select_as_str() {
276     let ret = jsonpath::select_as_str(
277         r#"
278     {
279         "school": {
280             "friends": [
281                     {"name": "친구1", "age": 20},
282                     {"name": "친구2", "age": 20}
283                 ]
284         },
285         "friends": [
286             {"name": "친구3", "age": 30},
287             {"name": "친구4"}
288         ]
289     }
290     "#,
291         "$..friends[0]",
292     )
293     .unwrap();
294 
295     assert_eq!(
296         ret,
297         r#"[{"name":"친구3","age":30},{"name":"친구1","age":20}]"#
298     );
299 }
300 
301 #[test]
readme_select_as()302 fn readme_select_as() {
303     #[derive(Deserialize, PartialEq, Debug)]
304     struct Person {
305         name: String,
306         age: u8,
307         phones: Vec<String>,
308     }
309 
310     let ret: Vec<Person> = jsonpath::select_as(
311         r#"{
312                     "person":
313                         {
314                             "name": "Doe John",
315                             "age": 44,
316                             "phones": [
317                                 "+44 1234567",
318                                 "+44 2345678"
319                             ]
320                         }
321                 }"#,
322         "$.person",
323     )
324     .unwrap();
325 
326     let person = Person {
327         name: "Doe John".to_string(),
328         age: 44,
329         phones: vec!["+44 1234567".to_string(), "+44 2345678".to_string()],
330     };
331 
332     assert_eq!(ret[0], person);
333 }
334 
335 #[test]
readme_compile()336 fn readme_compile() {
337     let first_firend = jsonpath::Compiled::compile("$..friends[0]").unwrap();
338 
339     let json_obj = json!({
340         "school": {
341             "friends": [
342                 {"name": "친구1", "age": 20},
343                 {"name": "친구2", "age": 20}
344             ]
345         },
346         "friends": [
347             {"name": "친구3", "age": 30},
348             {"name": "친구4"}
349     ]});
350 
351     let json = first_firend.select(&json_obj).unwrap();
352 
353     assert_eq!(
354         json,
355         vec![
356             &json!({"name": "친구3", "age": 30}),
357             &json!({"name": "친구1", "age": 20})
358         ]
359     );
360 }
361 
362 #[test]
readme_selector_fn()363 fn readme_selector_fn() {
364     let json_obj = json!({
365         "school": {
366             "friends": [
367                 {"name": "친구1", "age": 20},
368                 {"name": "친구2", "age": 20}
369             ]
370         },
371         "friends": [
372             {"name": "친구3", "age": 30},
373             {"name": "친구4"}
374     ]});
375 
376     let mut selector = jsonpath::selector(&json_obj);
377 
378     let json = selector("$..friends[0]").unwrap();
379 
380     assert_eq!(
381         json,
382         vec![
383             &json!({"name": "친구3", "age": 30}),
384             &json!({"name": "친구1", "age": 20})
385         ]
386     );
387 
388     let json = selector("$..friends[1]").unwrap();
389 
390     assert_eq!(
391         json,
392         vec![
393             &json!({"name": "친구4"}),
394             &json!({"name": "친구2", "age": 20})
395         ]
396     );
397 }
398 
399 #[test]
readme_selector_as()400 fn readme_selector_as() {
401     let json_obj = json!({
402         "school": {
403            "friends": [
404                 {"name": "친구1", "age": 20},
405                 {"name": "친구2", "age": 20}
406             ]
407         },
408         "friends": [
409             {"name": "친구3", "age": 30},
410             {"name": "친구4"}
411     ]});
412 
413     #[derive(Deserialize, PartialEq, Debug)]
414     struct Friend {
415         name: String,
416         age: Option<u8>,
417     }
418 
419     let mut selector = jsonpath::selector_as::<Friend>(&json_obj);
420 
421     let json = selector("$..friends[0]").unwrap();
422 
423     let ret = vec![
424         Friend {
425             name: "친구3".to_string(),
426             age: Some(30),
427         },
428         Friend {
429             name: "친구1".to_string(),
430             age: Some(20),
431         },
432     ];
433     assert_eq!(json, ret);
434 
435     let json = selector("$..friends[1]").unwrap();
436 
437     let ret = vec![
438         Friend {
439             name: "친구4".to_string(),
440             age: None,
441         },
442         Friend {
443             name: "친구2".to_string(),
444             age: Some(20),
445         },
446     ];
447 
448     assert_eq!(json, ret);
449 }
450 
451 #[test]
readme_delete()452 fn readme_delete() {
453     let json_obj = json!({
454         "school": {
455             "friends": [
456                 {"name": "친구1", "age": 20},
457                 {"name": "친구2", "age": 20}
458             ]
459         },
460         "friends": [
461             {"name": "친구3", "age": 30},
462             {"name": "친구4"}
463     ]});
464 
465     let ret = jsonpath::delete(json_obj, "$..[?(20 == @.age)]").unwrap();
466 
467     assert_eq!(
468         ret,
469         json!({
470             "school": {
471                 "friends": [
472                     null,
473                     null
474                 ]
475             },
476             "friends": [
477                 {"name": "친구3", "age": 30},
478                 {"name": "친구4"}
479         ]})
480     );
481 }
482 
483 #[test]
readme_delete2()484 fn readme_delete2() {
485     let json_obj = common::read_json("./benchmark/example.json");
486 
487     let ret = jsonpath::delete(json_obj, "$.store.book").unwrap();
488 
489     assert_eq!(
490         ret,
491         json!({
492             "store": {
493                 "book": null,
494                 "bicycle": {
495                     "color": "red",
496                     "price": 19.95
497                 }
498             },
499             "expensive": 10
500         })
501     );
502 }
503 
504 #[test]
readme_replace_with()505 fn readme_replace_with() {
506     let json_obj = json!({
507         "school": {
508             "friends": [
509                 {"name": "친구1", "age": 20},
510                 {"name": "친구2", "age": 20}
511             ]
512         },
513         "friends": [
514             {"name": "친구3", "age": 30},
515             {"name": "친구4"}
516     ]});
517 
518     let result = jsonpath::replace_with(json_obj, "$..[?(@.age == 20)].age", &mut |v| {
519         let age = if let Value::Number(n) = v {
520             n.as_u64().unwrap() * 2
521         } else {
522             0
523         };
524 
525         Some(json!(age))
526     })
527     .unwrap();
528 
529     assert_eq!(
530         result,
531         json!({
532             "school": {
533                 "friends": [
534                     {"name": "친구1", "age": 40},
535                     {"name": "친구2", "age": 40}
536                 ]
537             },
538             "friends": [
539                 {"name": "친구3", "age": 30},
540                 {"name": "친구4"}
541         ]})
542     );
543 }
544