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, JsonValueUpdater};
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 = (jsonpath::selector_as(&json_obj))("$..[?(@.age >= 30)]").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 mut 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     let mut updater = JsonValueUpdater::new(|v| {
216         let age = if let Value::Number(n) = v {
217             n.as_u64().unwrap() * 2
218         } else {
219             0
220         };
221 
222         Some(json!(age))
223     });
224     selector_mut
225         .str_path("$..[?(@.age == 20)].age")
226         .unwrap()
227         .value(&mut json_obj)
228         .replace_with(&mut updater)
229         .unwrap();
230 
231     assert_eq!(
232         json_obj,
233         json!({
234             "school": {
235                 "friends": [
236                     {"name": "친구1", "age": 40},
237                     {"name": "친구2", "age": 40}
238                 ]
239             },
240             "friends": [
241                 {"name": "친구3", "age": 30},
242                 {"name": "친구4"}
243         ]})
244     );
245 }
246 
247 #[test]
readme_select()248 fn readme_select() {
249     let json_obj = json!({
250         "school": {
251             "friends": [
252                 {"name": "친구1", "age": 20},
253                 {"name": "친구2", "age": 20}
254             ]
255         },
256         "friends": [
257             {"name": "친구3", "age": 30},
258             {"name": "친구4"}
259     ]});
260 
261     let json = jsonpath::select(&json_obj, "$..friends[0]").unwrap();
262 
263     assert_eq!(
264         json,
265         vec![
266             &json!({"name": "친구3", "age": 30}),
267             &json!({"name": "친구1", "age": 20})
268         ]
269     );
270 }
271 
272 #[test]
readme_select_as_str()273 fn readme_select_as_str() {
274     let ret = jsonpath::select_as_str(
275         r#"
276     {
277         "school": {
278             "friends": [
279                     {"name": "친구1", "age": 20},
280                     {"name": "친구2", "age": 20}
281                 ]
282         },
283         "friends": [
284             {"name": "친구3", "age": 30},
285             {"name": "친구4"}
286         ]
287     }
288     "#,
289         "$..friends[0]",
290     )
291     .unwrap();
292 
293     assert_eq!(
294         ret,
295         r#"[{"name":"친구3","age":30},{"name":"친구1","age":20}]"#
296     );
297 }
298 
299 #[test]
readme_select_as()300 fn readme_select_as() {
301     #[derive(Deserialize, PartialEq, Debug)]
302     struct Person {
303         name: String,
304         age: u8,
305         phones: Vec<String>,
306     }
307 
308     let json = serde_json::from_str(r#"{
309         "person":
310             {
311                 "name": "Doe John",
312                 "age": 44,
313                 "phones": [
314                     "+44 1234567",
315                     "+44 2345678"
316                 ]
317             }
318     }"#).unwrap();
319     let ret: Vec<Person> = (jsonpath::selector_as(&json))("$.person").unwrap();
320 
321     let person = Person {
322         name: "Doe John".to_string(),
323         age: 44,
324         phones: vec!["+44 1234567".to_string(), "+44 2345678".to_string()],
325     };
326 
327     assert_eq!(ret[0], person);
328 }
329 
330 #[test]
readme_compile()331 fn readme_compile() {
332     let first_firend = jsonpath::Compiled::compile("$..friends[0]").unwrap();
333 
334     let json_obj = json!({
335         "school": {
336             "friends": [
337                 {"name": "친구1", "age": 20},
338                 {"name": "친구2", "age": 20}
339             ]
340         },
341         "friends": [
342             {"name": "친구3", "age": 30},
343             {"name": "친구4"}
344     ]});
345 
346     let json = first_firend.select(&json_obj).unwrap();
347 
348     assert_eq!(
349         json,
350         vec![
351             &json!({"name": "친구3", "age": 30}),
352             &json!({"name": "친구1", "age": 20})
353         ]
354     );
355 }
356 
357 #[test]
readme_selector_fn()358 fn readme_selector_fn() {
359     let json_obj = json!({
360         "school": {
361             "friends": [
362                 {"name": "친구1", "age": 20},
363                 {"name": "친구2", "age": 20}
364             ]
365         },
366         "friends": [
367             {"name": "친구3", "age": 30},
368             {"name": "친구4"}
369     ]});
370 
371     let mut selector = jsonpath::selector(&json_obj);
372 
373     let json = selector("$..friends[0]").unwrap();
374 
375     assert_eq!(
376         json,
377         vec![
378             &json!({"name": "친구3", "age": 30}),
379             &json!({"name": "친구1", "age": 20})
380         ]
381     );
382 
383     let json = selector("$..friends[1]").unwrap();
384 
385     assert_eq!(
386         json,
387         vec![
388             &json!({"name": "친구4"}),
389             &json!({"name": "친구2", "age": 20})
390         ]
391     );
392 }
393 
394 #[test]
readme_selector_as()395 fn readme_selector_as() {
396     let json_obj = json!({
397         "school": {
398            "friends": [
399                 {"name": "친구1", "age": 20},
400                 {"name": "친구2", "age": 20}
401             ]
402         },
403         "friends": [
404             {"name": "친구3", "age": 30},
405             {"name": "친구4"}
406     ]});
407 
408     #[derive(Deserialize, PartialEq, Debug)]
409     struct Friend {
410         name: String,
411         age: Option<u8>,
412     }
413 
414     let mut selector = jsonpath::selector_as::<Friend>(&json_obj);
415 
416     let json = selector("$..friends[0]").unwrap();
417 
418     let ret = vec![
419         Friend {
420             name: "친구3".to_string(),
421             age: Some(30),
422         },
423         Friend {
424             name: "친구1".to_string(),
425             age: Some(20),
426         },
427     ];
428     assert_eq!(json, ret);
429 
430     let json = selector("$..friends[1]").unwrap();
431 
432     let ret = vec![
433         Friend {
434             name: "친구4".to_string(),
435             age: None,
436         },
437         Friend {
438             name: "친구2".to_string(),
439             age: Some(20),
440         },
441     ];
442 
443     assert_eq!(json, ret);
444 }
445 
446 #[test]
readme_delete()447 fn readme_delete() {
448     let json_obj = json!({
449         "school": {
450             "friends": [
451                 {"name": "친구1", "age": 20},
452                 {"name": "친구2", "age": 20}
453             ]
454         },
455         "friends": [
456             {"name": "친구3", "age": 30},
457             {"name": "친구4"}
458     ]});
459 
460     let ret = jsonpath::delete(json_obj, "$..[?(20 == @.age)]").unwrap();
461 
462     assert_eq!(
463         ret,
464         json!({
465             "school": {
466                 "friends": [
467                     null,
468                     null
469                 ]
470             },
471             "friends": [
472                 {"name": "친구3", "age": 30},
473                 {"name": "친구4"}
474         ]})
475     );
476 }
477 
478 #[test]
readme_delete2()479 fn readme_delete2() {
480     let json_obj = common::read_json("./benchmark/example.json");
481 
482     let ret = jsonpath::delete(json_obj, "$.store.book").unwrap();
483 
484     assert_eq!(
485         ret,
486         json!({
487             "store": {
488                 "book": null,
489                 "bicycle": {
490                     "color": "red",
491                     "price": 19.95
492                 }
493             },
494             "expensive": 10
495         })
496     );
497 }
498 
499 #[test]
readme_replace_with()500 fn readme_replace_with() {
501     let json_obj = json!({
502         "school": {
503             "friends": [
504                 {"name": "친구1", "age": 20},
505                 {"name": "친구2", "age": 20}
506             ]
507         },
508         "friends": [
509             {"name": "친구3", "age": 30},
510             {"name": "친구4"}
511     ]});
512 
513     let result = jsonpath::replace_with(json_obj, "$..[?(@.age == 20)].age", &mut |v| {
514         let age = if let Value::Number(n) = v {
515             n.as_u64().unwrap() * 2
516         } else {
517             0
518         };
519 
520         Some(json!(age))
521     })
522     .unwrap();
523 
524     assert_eq!(
525         result,
526         json!({
527             "school": {
528                 "friends": [
529                     {"name": "친구1", "age": 40},
530                     {"name": "친구2", "age": 40}
531                 ]
532             },
533             "friends": [
534                 {"name": "친구3", "age": 30},
535                 {"name": "친구4"}
536         ]})
537     );
538 }
539