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