1mod result_acceptor;
2use result_acceptor::*;
3
4use std::iter::Peekable;
5
6use serde_json::{Map, Value};
7
8use crate::{
9 tokenizer::{
10 ArraySlice, Comparator, Expression, PropertyPathToken, RootPathToken, ScanPathToken, Token,
11 },
12 JsonPathError, JsonPathResult,
13};
14
15pub struct Eval {
16 result_acceptor: Box<dyn ResultAcceptor>,
17}
18
19impl Eval {
20 pub fn new() -> Self {
21 Eval {
22 result_acceptor: Box::new(ScalarResultAcceptor::new()),
23 }
24 }
25 pub fn eval(&mut self, json: &Value, tokens: impl AsRef<Vec<Token>>) -> JsonPathResult<Value> {
26 let mut tokens = tokens.as_ref().iter().peekable();
27
28 match tokens.next() {
29 Some(Token::Root(root)) => self.visit_root(root, json, &mut tokens)?,
30 None => {
31 return Err(JsonPathError::EvaluationError(
32 "Empty jsonpath provided".to_string(),
33 ))
34 }
35 Some(_) => {
36 return Err(JsonPathError::EvaluationError(
37 "Invalid start token for the given jsonpath".to_string(),
38 ))
39 }
40 }
41
42 self.result_acceptor.result()
43 }
44
45 fn push_result(&mut self, value: Option<Value>) -> JsonPathResult<()> {
46 self.result_acceptor.accept(value)
47 }
48
49 fn visit_next_token<'a>(
50 &mut self,
51 json: &Value,
52 tokens: &mut Peekable<impl Iterator<Item = &'a Token> + Clone>,
53 ) -> JsonPathResult<()> {
54 match tokens.next() {
55 Some(Token::Root(_root)) => unimplemented!(),
56 Some(Token::Property(property)) => self.visit_property(property, json, tokens),
57 Some(Token::ArrayIndex { indices }) => self.visit_array_index(indices, json, tokens),
58 Some(Token::ArraySlice(array_slice)) => {
59 self.visit_array_slice(array_slice, json, tokens)
60 }
61 Some(Token::Predicate(expression)) => self.visit_predicate(expression, json, tokens),
62 Some(Token::Function(_)) => todo!(),
63 Some(Token::Scan(scan)) => self.visit_scan(scan, json, tokens),
64 Some(Token::Wildcard) => self.visit_wildchard(json, tokens),
65 None => Ok(()),
66 }
67 }
68
69 fn visit_root<'a>(
70 &mut self,
71 _token: &RootPathToken,
72 json: &Value,
73 tokens: &mut Peekable<impl Iterator<Item = &'a Token> + Clone>,
74 ) -> JsonPathResult<()> {
75 match tokens.peek() {
76 None => self.push_result(Some(json.clone())),
77 Some(_) => self.visit_next_token(json, tokens),
78 }
79 }
80
81 fn visit_property<'a>(
82 &mut self,
83 token: &PropertyPathToken,
84 object: &Value,
85 tokens: &mut Peekable<impl Iterator<Item = &'a Token> + Clone>,
86 ) -> JsonPathResult<()> {
87 let object = match object {
88 Value::Object(object) => object,
89 _ => return Ok(()),
90 };
91
92 if token.properties.len() > 1 {
93 match tokens.peek() {
94 None => {
95 let mut result = Map::new();
97 for prop in token.properties.iter() {
98 match object.get(prop) {
99 Some(v) => result.insert(prop.to_string(), v.clone()),
100 None => result.insert(prop.to_string(), Value::Null),
102 };
103 }
104 self.push_result(Some(Value::Object(result)))
105 }
106 Some(_) => {
107 self.use_array_result_register();
109
110 for prop in token.properties.iter() {
111 self.handle_object_property(prop, object, &mut tokens.clone())?;
112 }
113 Ok(())
114 }
115 }
116 } else {
117 let prop = token.properties.first().unwrap();
119 self.handle_object_property(prop, object, tokens)
120 }
121 }
122
123 fn handle_object_property<'a>(
124 &mut self,
125 prop: &String,
126 object: &Map<String, Value>,
127 tokens: &mut Peekable<impl Iterator<Item = &'a Token> + Clone>,
128 ) -> JsonPathResult<()> {
129 match object.get(prop) {
130 Some(v) => match tokens.peek() {
131 None => self.push_result(Some(v.clone())),
132 Some(_) => self.visit_next_token(v, tokens),
133 },
134 None => self.push_result(None),
135 }
136 }
137}
138
139impl Eval {
141 fn use_array_result_register(&mut self) {
143 if self.result_acceptor.is_scalar() {
144 self.result_acceptor = Box::new(ArrayResultRegister::new())
145 }
146 }
147
148 fn visit_scan<'a>(
149 &mut self,
150 _token: &ScanPathToken,
151 json: &Value,
152 tokens: &mut Peekable<impl Iterator<Item = &'a Token> + Clone>,
153 ) -> JsonPathResult<()> {
154 if !json.is_array() && !json.is_object() {
155 return Err(JsonPathError::EvaluationError(
156 "Properties scan ('..') can only run on array or object values.".to_string(),
157 ));
158 }
159 self.use_array_result_register();
160 self.walk(json, tokens)
161 }
162
163 fn walk<'a>(
164 &mut self,
165 json: &Value,
166 tokens: &mut Peekable<impl Iterator<Item = &'a Token> + Clone>,
167 ) -> JsonPathResult<()> {
168 self.visit_next_token(json, &mut tokens.clone())?;
169 match json {
170 Value::Object(object) => {
171 for (_k, v) in object {
172 self.walk(v, &mut tokens.clone())?;
173 }
174 }
175 Value::Array(array) => {
176 for v in array {
177 self.walk(v, &mut tokens.clone())?;
178 }
179 }
180 _ => {}
181 }
182 Ok(())
183 }
184}
185
186impl Eval {
188 fn visit_array_index<'a>(
189 &mut self,
190 indices: &Vec<i32>,
191 json: &Value,
192 tokens: &mut Peekable<impl Iterator<Item = &'a Token> + Clone>,
193 ) -> JsonPathResult<()> {
194 let array = json.as_array().ok_or(JsonPathError::EvaluationError(
195 "Running array index op on non-array object".to_string(),
196 ))?;
197
198 if indices.is_empty() {
199 Err(JsonPathError::EvaluationError(
200 "Invalid array index token, zero index given.".to_string(),
201 ))
202 } else if indices.len() == 1 {
203 let index = *indices.first().unwrap();
204 self.handle_array_index(array, index, tokens)
205 } else {
206 self.use_array_result_register();
207 for index in indices {
208 self.handle_array_index(array, *index, &mut tokens.clone())?;
209 }
210 Ok(())
211 }
212 }
213
214 fn handle_array_index<'a>(
215 &mut self,
216 array: &Vec<Value>,
217 mut index: i32,
218 tokens: &mut Peekable<impl Iterator<Item = &'a Token> + Clone>,
219 ) -> JsonPathResult<()> {
220 if index < 0 {
221 index += array.len() as i32;
223 }
224 if index >= 0 && index < array.len() as i32 {
225 let value = array.get(index as usize).unwrap();
226 match tokens.peek() {
227 None => self.push_result(Some(value.clone())),
228 Some(_t) => self.visit_next_token(value, tokens),
229 }
230 } else {
231 Ok(())
232 }
233 }
234
235 fn visit_array_slice<'a>(
236 &mut self,
237 slice: &ArraySlice,
238 json: &Value,
239 tokens: &mut Peekable<impl Iterator<Item = &'a Token> + Clone>,
240 ) -> JsonPathResult<()> {
241 let array = json.as_array().ok_or(JsonPathError::EvaluationError(
242 "Running array index op on non-array object".to_string(),
243 ))?;
244 self.use_array_result_register();
245 match slice {
246 ArraySlice::From(from) => {
247 let mut start = *from;
248 if start < 0 {
249 start = (array.len() as i32 + start).max(0);
250 }
251 for index in start..array.len() as i32 {
252 self.handle_array_index(array, index, &mut tokens.clone())?;
253 }
254 Ok(())
255 }
256 ArraySlice::To(to) => {
257 let mut end = *to;
258 if end < 0 {
259 end += array.len() as i32;
260 }
261 for index in 0..end {
262 self.handle_array_index(array, index, &mut tokens.clone())?;
263 }
264 Ok(())
265 }
266 ArraySlice::Between(from, to) => {
267 let mut start = *from;
268 let mut end = *to;
269 if end < 0 {
270 end += array.len() as i32;
272 }
273 if start < 0 {
274 start = (array.len() as i32 + start).max(0);
276 }
277 if start < end && !array.is_empty() {
278 for index in start..end {
279 self.handle_array_index(array, index, &mut tokens.clone())?;
280 }
281 }
282 Ok(())
283 }
284 }
285 }
286}
287
288impl Eval {
289 fn visit_wildchard<'a>(
290 &mut self,
291 json: &Value,
292 tokens: &mut Peekable<impl Iterator<Item = &'a Token> + Clone>,
293 ) -> JsonPathResult<()> {
294 self.use_array_result_register();
295 match json {
296 Value::Array(array) => {
297 for index in 0..array.len() {
298 self.handle_array_index(array, index as i32, &mut tokens.clone())?;
299 }
300 }
301 Value::Object(object) => {
302 for prop in object.keys() {
303 self.handle_object_property(prop, object, &mut tokens.clone())?;
304 }
305 }
306 _ => {
307 return Err(JsonPathError::EvaluationError(
308 "Expect array or object for wildcard query.".to_string(),
309 ));
310 }
311 }
312 Ok(())
313 }
314}
315
316impl Eval {
317 fn visit_predicate<'a>(
318 &mut self,
319 expression: &Expression,
320 json: &Value,
321 tokens: &mut Peekable<impl Iterator<Item = &'a Token> + Clone>,
322 ) -> JsonPathResult<()> {
323 let result = self.eval_expr(expression, json)?;
324 let bool = Self::get_bool(result);
325 match (bool, tokens.peek()) {
326 (true, None) => self.push_result(Some(json.clone())),
327 (true, Some(_)) => self.visit_next_token(json, tokens),
328 _ => Ok(()),
329 }
330 }
331
332 fn get_bool(value: Value) -> bool {
333 match value {
334 Value::Bool(b) => b,
335 Value::Null => false,
336 _ => true,
337 }
338 }
339
340 fn eval_expr(&self, expression: &Expression, json: &Value) -> JsonPathResult<Value> {
341 let result = match expression {
342 Expression::JsonQuery(tokens) => {
343 let mut eval = Eval::new();
344 eval.eval(json, tokens)?
346 }
347 Expression::Literal(v) => v.clone(),
348 Expression::Not(inner) => {
349 let r = self.eval_expr(inner, json)?;
350 match r {
351 Value::Bool(b) => Value::Bool(!b),
352 Value::Null => Value::Bool(true),
353 _ => Value::Bool(false),
354 }
355 }
356 Expression::Array(v) => {
357 let values = v
358 .iter()
359 .map(|e| self.eval_expr(e, json))
360 .collect::<JsonPathResult<Vec<Value>>>()?;
361 Value::Array(values)
362 }
363 Expression::CompareExpr { op, left, right } => {
364 let left = self.eval_expr(left, json)?;
365 let right = self.eval_expr(right, json)?;
366 let result = match op {
367 Comparator::Eq => left.eq(&right),
368 Comparator::Neq => !left.eq(&right),
369 Comparator::Gt => match (left, right) {
370 (Value::Number(l), Value::Number(r)) => l.as_f64() > r.as_f64(),
371 _ => false,
372 },
373 Comparator::GtEq => match (left, right) {
374 (Value::Number(l), Value::Number(r)) => l.as_f64() >= r.as_f64(),
375 _ => false,
376 },
377 Comparator::Lt => match (left, right) {
378 (Value::Number(l), Value::Number(r)) => l.as_f64() < r.as_f64(),
379 _ => false,
380 },
381 Comparator::LtEq => match (left, right) {
382 (Value::Number(l), Value::Number(r)) => l.as_f64() <= r.as_f64(),
383 _ => false,
384 },
385 Comparator::RegExpMatch => todo!(), Comparator::AND => Self::get_bool(left) && Self::get_bool(right),
387 Comparator::OR => Self::get_bool(left) || Self::get_bool(right),
388 Comparator::IN => match right {
389 Value::Array(values) => values.contains(&left),
390 _ => false,
391 },
392 Comparator::NIN => match right {
393 Value::Array(values) => !values.contains(&left),
394 _ => false,
395 },
396 Comparator::SubsetOf => match (left, right) {
397 (Value::Array(l), Value::Array(r)) => l.iter().all(|c| r.contains(c)),
398 _ => false,
399 },
400 Comparator::AnyOf => match (left, right) {
401 (Value::Array(l), Value::Array(r)) => l.iter().any(|c| r.contains(c)),
402 _ => false,
403 },
404 Comparator::NoneOf => match (left, right) {
405 (Value::Array(l), Value::Array(r)) => !l.iter().any(|c| r.contains(c)),
406 _ => false,
407 },
408 Comparator::Contains => match (left, right) {
409 (Value::Array(values), r) => values.contains(&r),
410 (Value::String(l), Value::String(r)) => l.contains(&r),
411 _ => false,
412 },
413 Comparator::SizeOf => match (left, right) {
414 (Value::Array(values), Value::Number(n)) => {
415 values.len() as i64 == n.as_i64().unwrap_or(-1)
416 }
417 (Value::String(s), Value::Number(n)) => {
418 s.len() as i64 == n.as_i64().unwrap_or(-1)
419 }
420 _ => false,
421 },
422 Comparator::Empty => match (left, right) {
423 (Value::Array(values), Value::Bool(b)) => values.is_empty() == b,
424 (Value::String(s), Value::Bool(b)) => s.is_empty() == b,
425 (Value::Null, Value::Bool(b)) => b,
426 _ => false,
427 },
428 };
429 Value::Bool(result)
430 }
431 };
432 Ok(result)
433 }
434}
435
436#[cfg(test)]
437mod test {
438 use serde_json::{json, Value};
439
440 use crate::{tokenizer::Tokenizer, JsonPathResult};
441
442 use super::Eval;
443
444 pub trait JsonPathQuery {
445 fn query(&self, json_path: &str) -> JsonPathResult<Value>;
446 }
447
448 impl JsonPathQuery for Value {
449 fn query(&self, json_path: &str) -> JsonPathResult<Value> {
450 let tz = Tokenizer::new();
451 let tokens = tz.tokenize(json_path)?;
452 let mut eval = Eval::new();
453 eval.eval(self, tokens)
454 }
455 }
456
457 #[test]
458 fn can_query_root_node() {
459 let json = json!({"data": {"msg": "hello"}});
460 assert_eq!(json.query("$"), Ok(json));
461 }
462
463 #[test]
464 fn can_query_single_property() {
465 assert_eq!(
466 Ok(json!("hello")),
467 json!({"data": {"msg": "hello"}}).query("$.data.msg")
468 );
469 }
470
471 #[test]
472 fn can_query_single_bracket_property() {
473 assert_eq!(
474 Ok(json!("hello")),
475 json!({"data": {"msg": "hello"}}).query("$[\"data\"].msg")
476 )
477 }
478
479 #[test]
480 fn can_query_multiple_bracket_properties() {
481 assert_eq!(
482 Ok(json!(["hello", "jsonpath"])),
483 json!({"data": {"msg": "hello"}, "value": {"msg": "jsonpath"}})
484 .query("$['data','value'].msg")
485 );
486 }
487
488 #[test]
489 fn can_query_and_merge_multiple_bracket_properties() {
490 let json = json!({"data": {"msg1": "hello", "msg2": "jsonpath", "msg3": "xxx"}});
491 assert_eq!(
492 Ok(json!({"msg1": "hello", "msg2": "jsonpath"})),
493 json.query("$.data['msg1','msg2']")
494 )
495 }
496
497 #[test]
498 fn can_scan_properties() {
499 let json = json!({"data": {"item1": {"msg": "hello"}, "item2": {"msg": "jsonpath"}}});
500 assert_eq!(Ok(json!(["hello", "jsonpath"])), json.query("$.data..msg"))
501 }
502
503 #[test]
504 fn can_scan_properties_with_arrays() {
505 let json = json!({"data": {"items": [{"msg": "jsonpath"}, {"msg": "!"}], "msg": "hello"}});
506 assert_eq!(
507 Ok(json!(["hello", "jsonpath", "!"])),
508 json.query("$.data..msg")
509 )
510 }
511
512 #[test]
513 fn support_array_index_with_single_index() {
514 let json = json!({"data": ["item 0", "item 1", "item 2"]});
515 assert_eq!(Ok(json!("item 0")), json.query("$.data[0]"));
516 assert_eq!(Ok(json!("item 1")), json.query("$.data[1]"));
517 assert_eq!(Ok(json!("item 2")), json.query("$.data[2]"));
518 assert_eq!(Ok(Value::Null), json.query("$.data[3]"));
519 assert_eq!(Ok(json!("item 2")), json.query("$.data[-1]"));
520 assert_eq!(Ok(json!("item 1")), json.query("$.data[-2]"));
521 assert_eq!(Ok(json!("item 0")), json.query("$.data[-3]"));
522 assert_eq!(Ok(Value::Null), json.query("$.data[-4]"));
523 }
524
525 #[test]
526 fn support_array_index_with_empty_array() {
527 let json = json!({"data": []});
528 assert_eq!(Ok(Value::Null), json.query("$.data[0]"));
529 }
530
531 #[test]
532 fn support_array_index_with_multiple_indices() {
533 let json = json!({"data": ["item 0", "item 1", "item 2"]});
534 assert_eq!(Ok(json!(["item 0", "item 2"])), json.query("$.data[0,2]"));
535 assert_eq!(Ok(json!(["item 0", "item 2"])), json.query("$.data[0,-1]"));
536 assert_eq!(Ok(json!(["item 1", "item 1"])), json.query("$.data[1,1]"));
537 }
538
539 #[test]
540 fn support_array_slice() {
541 let json = json!({"data": ["item 0", "item 1", "item 2"]});
542 assert_eq!(
543 Ok(json!(["item 0", "item 1", "item 2"])),
544 json.query("$.data[0:3]")
545 );
546 assert_eq!(
547 Ok(json!(["item 0", "item 1", "item 2"])),
548 json.query("$.data[:3]")
549 );
550 assert_eq!(Ok(json!(["item 1", "item 2"])), json.query("$.data[1:]"));
551 assert_eq!(Ok(json!(["item 0", "item 1"])), json.query("$.data[0:-1]"));
552 assert_eq!(Ok(json!(["item 0", "item 1"])), json.query("$.data[:-1]"));
553 assert_eq!(Ok(json!(["item 0", "item 1"])), json.query("$.data[-5:-1]"));
554 assert_eq!(
555 Ok(json!(["item 0", "item 1", "item 2"])),
556 json.query("$.data[-5:]")
557 );
558 }
559
560 #[test]
561 fn support_wildcard_query_on_objects() {
562 let json = json!({"data": {"0": {"msg": "item 0"}, "1": {"msg": "item 1"}}});
563 assert_eq!(Ok(json!(["item 0", "item 1"])), json.query("$.data[*].msg"));
564 let json =
565 json!({"data": {"0": {"msg": {"msg": "item 0"}}, "1": {"msg": {"msg": "item 1"}}}});
566 assert_eq!(
567 Ok(json!(["item 0", "item 1"])),
568 json.query("$.data[*].msg.msg")
569 );
570 assert_eq!(
571 Ok(json!(["item 0", "item 1"])),
572 json.query("$.data.*.msg.msg")
573 );
574 }
575
576 #[test]
577 fn support_wildcard_query_on_arrays() {
578 let json = json!({"data": [{"msg": "item 0"}, {"msg": "item 1"}]});
579 assert_eq!(Ok(json!(["item 0", "item 1"])), json.query("$.data[*].msg"));
580 let json = json!({"data": [ {"msg": {"msg": "item 0"}}, {"msg": {"msg": "item 1"}}]});
581 assert_eq!(
582 Ok(json!(["item 0", "item 1"])),
583 json.query("$.data[*].msg.msg")
584 );
585 }
586
587 #[test]
588 fn support_simple_filters() {
589 let json = json!({"data": [{"msg": "item 0"}, {"msg": "item 1"}]});
590 assert_eq!(
591 Ok(json!(["item 0", "item 1"])),
592 json.query("$.data[*][?(@.msg)].msg")
593 );
594 }
595
596 #[test]
597 fn support_simple_filters_2() {
598 let json = json!({"data": [{"msg": "item 0", "id": 10}, {"msg": "item 1", "id": 11}, {"msg": null, "id": 10}]});
599 assert_eq!(
600 Ok(json!(["item 0"])),
601 json.query("$.data[*][?(@.msg && @.id == 10)].msg")
602 );
603 }
604
605 #[test]
606 fn support_filters_with_in() {
607 let json = json!({"data": [{"msg": "item 0", "id": 10}, {"msg": "item 1", "id": 11}, {"msg": null, "id": 10}]});
608 assert_eq!(
609 Ok(json!(["item 0"])),
610 json.query("$.data[*][?(@.msg in ['item 0'])].msg")
611 );
612 assert_eq!(
613 Ok(json!(["item 0", "item 1", null])),
614 json.query("$.data[*][?(@.id in [10, 11])].msg")
615 );
616 }
617
618 #[test]
619 fn support_filters_with_in2() {
620 let json = json!({"data": [{"msg": "item 0", "id": 10}, {"msg": "item 1", "id": 11}, {"msg": null, "id": 10}]});
621 assert_eq!(
622 Ok(json!(["item 1", null])),
623 json.query("$.data[*][?(@.msg nin ['item 0'])].msg")
624 );
625 assert_eq!(
626 Ok(json!([])),
627 json.query("$.data[*][?(@.id nin [10, 11])].msg")
628 );
629 }
630
631 #[test]
632 fn support_filters_with_subsetof() {
633 let json = json!({"data": [{"sizes": ["M", "L"], "id": 10}, {"sizes": ["M", "XXL"], "id": 11}, {"sizes": ["M"], "id": 12}]});
634 assert_eq!(
635 Ok(json!([10, 12])),
636 json.query("$.data[*][?(@.sizes subsetof ['M', \"L\"])].id")
637 );
638 }
639
640 #[test]
641 fn support_filters_with_anyof() {
642 let json = json!({"data": [{"sizes": ["M", "L"], "id": 10}, {"sizes": ["M", "XXL"], "id": 11}, {"sizes": ["XXL"], "id": 12}]});
643 assert_eq!(
644 Ok(json!([10, 11])),
645 json.query("$.data[*][?(@.sizes anyof ['M', \"L\"])].id")
646 );
647 }
648
649 #[test]
650 fn support_filters_with_noneof() {
651 let json = json!({"data": [{"sizes": ["M", "L"], "id": 10}, {"sizes": ["M", "XXL"], "id": 11}, {"sizes": ["XXL"], "id": 12}]});
652 assert_eq!(
653 Ok(json!([12])),
654 json.query("$.data[*][?(@.sizes noneof ['M', \"L\"])].id")
655 );
656 }
657
658 #[test]
659 fn support_filters_with_contains() {
660 let json = json!({"data": [{"sizes": ["M", "L"], "id": 10}, {"sizes": ["M", "XXL"], "id": 11}, {"sizes": ["XXL"], "id": 12}]});
661 assert_eq!(
662 Ok(json!([10, 11])),
663 json.query("$.data[*][?(@.sizes contains 'M')].id")
664 );
665
666 let json = json!({"data": [{"msg": "item 0", "id": 10}, {"msg": "item 1", "id": 11}, {"msg": null, "id": 10}]});
667 assert_eq!(
668 Ok(json!(["item 0"])),
669 json.query("$.data[*][?(@.msg contains '0')].msg")
670 );
671 }
672
673 #[test]
674 fn support_filters_with_sizeof() {
675 let json = json!({"data": [{"sizes": ["M", "L"], "id": 10}, {"sizes": ["M", "XXL"], "id": 11}, {"sizes": ["XXL"], "id": 12}]});
676 assert_eq!(
677 Ok(json!([10, 11])),
678 json.query("$.data[*][?(@.sizes size 2)].id")
679 );
680
681 let json = json!({"data": [{"msg": "item 0", "id": 10}, {"msg": "item 1", "id": 11}, {"msg": null, "id": 10}]});
682 assert_eq!(
683 Ok(json!(["item 0", "item 1"])),
684 json.query("$.data[*][?(@.msg size 6)].msg")
685 );
686 }
687
688 #[test]
689 fn support_filters_with_empty_op() {
690 let json = json!({"data": [{"sizes": ["M", "L"], "id": 10}, {"sizes": ["M", "XXL"], "id": 11}, {"sizes": [], "id": 12}]});
691 assert_eq!(
692 Ok(json!([10, 11])),
693 json.query("$.data[*][?(@.sizes empty false)].id")
694 );
695
696 let json = json!({"data": [{"msg": "item 0", "id": 10}, {"msg": "item 1", "id": 11}, {"msg": null, "id": 12}]});
697 assert_eq!(
698 Ok(json!([12])),
699 json.query("$.data[*][?(@.msg empty true)].id")
700 );
701 }
702
703 #[test]
704 fn support_filters_with_not_op() {
705 let json = json!({"data": [{"sizes": ["M", "L"], "id": 10}, {"sizes": ["M", "XXL"], "id": 11}, {"sizes": [], "id": 12}]});
706 assert_eq!(
707 Ok(json!([12])),
708 json.query("$.data[*][?(!(@.sizes empty false))].id")
709 );
710
711 let json = json!({"data": [{"msg": "item 0", "id": 10}, {"msg": "item 1", "id": 11}, {"msg": null, "id": 12}]});
712 assert_eq!(Ok(json!([12])), json.query("$.data[*][?(!@.msg)].id"));
713 }
714
715 #[test]
716 fn support_scan_and_filter() {
717 let json = json!([1, 2, 3]);
718 assert_eq!(Ok(json!([1, 2, 3])), json.query("$..[?(@>=1)]"));
719 }
720}