1use std::collections::HashSet;
2use std::fmt;
3
4use serde_json::map::Entry;
5use serde_json::{Number, Value};
6
7use parser::*;
8
9use self::expr_term::*;
10use self::value_walker::JValueWalker;
11
12mod cmp;
13mod expr_term;
14mod value_walker;
15
16fn to_f64(n: &Number) -> f64 {
17 if n.is_i64() {
18 n.as_i64().unwrap() as f64
19 } else if n.is_f64() {
20 n.as_f64().unwrap()
21 } else {
22 n.as_u64().unwrap() as f64
23 }
24}
25
26fn abs_index(n: isize, len: usize) -> usize {
27 if n < 0_isize {
28 (n + len as isize).max(0) as usize
29 } else {
30 n.min(len as isize) as usize
31 }
32}
33
34#[derive(Debug, PartialEq)]
35enum FilterKey {
36 String(String),
37 All,
38}
39
40pub enum JsonPathError {
41 EmptyPath,
42 EmptyValue,
43 CantFlatten(Vec<Value>),
44 Path(String),
45 Serde(String),
46}
47
48impl fmt::Debug for JsonPathError {
49 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
50 write!(f, "{}", self)
51 }
52}
53
54impl fmt::Display for JsonPathError {
55 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
56 match self {
57 JsonPathError::EmptyPath => f.write_str("path not set"),
58 JsonPathError::EmptyValue => f.write_str("json value not set"),
59 JsonPathError::CantFlatten(values) => {
60 write!(f, "json value '{:?}' can't be flattened", values)
61 }
62 JsonPathError::Path(msg) => f.write_str(&format!("path error: \n{}\n", msg)),
63 JsonPathError::Serde(msg) => f.write_str(&format!("serde error: \n{}\n", msg)),
64 }
65 }
66}
67
68#[derive(Debug, Default)]
69struct FilterTerms<'a>(Vec<Option<ExprTerm<'a>>>);
70
71impl<'a> FilterTerms<'a> {
72 fn new_filter_context(&mut self) {
73 self.0.push(None);
74 debug!("new_filter_context: {:?}", self.0);
75 }
76
77 fn is_term_empty(&self) -> bool {
78 self.0.is_empty()
79 }
80
81 fn push_term(&mut self, term: Option<ExprTerm<'a>>) {
82 self.0.push(term);
83 }
84
85 #[allow(clippy::option_option)]
86 fn pop_term(&mut self) -> Option<Option<ExprTerm<'a>>> {
87 self.0.pop()
88 }
89
90 fn filter_json_term<
91 F: Fn(&Vec<&'a Value>, &mut Vec<&'a Value>, &mut HashSet<usize>) -> FilterKey,
92 >(
93 &mut self,
94 e: ExprTerm<'a>,
95 fun: F,
96 ) {
97 debug!("filter_json_term: {:?}", e);
98
99 if let ExprTerm::Json(rel, fk, vec) = e {
100 let mut tmp = Vec::new();
101 let mut not_matched = HashSet::new();
102 let filter_key = if let Some(FilterKey::String(key)) = fk {
103 let key_contained = &vec
104 .iter()
105 .map(|v| match v {
106 Value::Object(map) if map.contains_key(&key) => map.get(&key).unwrap(),
107 _ => v,
108 })
109 .collect();
110 fun(key_contained, &mut tmp, &mut not_matched)
111 } else {
112 fun(&vec, &mut tmp, &mut not_matched)
113 };
114
115 if rel.is_some() {
116 self.0
117 .push(Some(ExprTerm::Json(rel, Some(filter_key), tmp)));
118 } else {
119 let filtered: Vec<&Value> = vec
120 .iter()
121 .enumerate()
122 .filter(|(idx, _)| !not_matched.contains(idx))
123 .map(|(_, v)| *v)
124 .collect();
125
126 self.0
127 .push(Some(ExprTerm::Json(Some(filtered), Some(filter_key), tmp)));
128 }
129 } else {
130 unreachable!("unexpected: ExprTerm: {:?}", e);
131 }
132 }
133
134 fn push_json_term<
135 F: Fn(&Vec<&'a Value>, &mut Vec<&'a Value>, &mut HashSet<usize>) -> FilterKey,
136 FF: Fn(&Vec<&'a Value>, &mut Vec<&'a Value>, &mut HashSet<usize>) -> FilterKey,
137 >(
138 &mut self,
139 current: &Option<Vec<&'a Value>>,
140 values: Option<Box<dyn ExactSizeIterator<Item = &'a Value> + 'a>>,
141 fun: F,
142 fun_flattened: FF,
143 ) {
144 debug!("push_json_term: {:?}", ¤t);
145
146 if let Some(current) = ¤t {
147 let mut tmp = Vec::new();
148 let mut not_matched = HashSet::new();
149 let filter_key = fun(current, &mut tmp, &mut not_matched);
150 self.0
151 .push(Some(ExprTerm::Json(None, Some(filter_key), tmp)));
152 } else {
153 if let Some(values) = values {
154 let mut tmp = Vec::new();
155 let mut not_matched = HashSet::new();
156 let values = values.collect();
157 let filter_key = fun_flattened(&values, &mut tmp, &mut not_matched);
158 self.0
159 .push(Some(ExprTerm::Json(None, Some(filter_key), tmp)));
160 }
161 }
162 }
163
164 fn filter<
165 F: Fn(&Vec<&'a Value>, &mut Vec<&'a Value>, &mut HashSet<usize>) -> FilterKey,
166 FF: Fn(&Vec<&'a Value>, &mut Vec<&'a Value>, &mut HashSet<usize>) -> FilterKey,
167 >(
168 &mut self,
169 current: &Option<Vec<&'a Value>>,
170 values: Option<Box<dyn ExactSizeIterator<Item = &'a Value> + 'a>>,
171 fun: F,
172 fun_flattened: FF,
173 ) {
174 if let Some(peek) = self.0.pop() {
175 if let Some(e) = peek {
176 self.filter_json_term(e, fun);
177 } else {
178 self.push_json_term(current, values, fun, fun_flattened);
179 }
180 }
181 }
182
183 fn filter_all_with_str(
184 &mut self,
185 current: &Option<Vec<&'a Value>>,
186 values: Option<Box<dyn ExactSizeIterator<Item = &'a Value> + 'a>>,
187 key: &str,
188 ) {
189 self.filter(
190 current,
191 values,
192 |vec, tmp, _| {
193 JValueWalker::all_with_str(&vec, tmp, key, true);
194 FilterKey::All
195 },
196 |_, _, _| FilterKey::All,
197 );
198
199 debug!("filter_all_with_str : {}, {:?}", key, self.0);
200 }
201
202 fn filter_next_with_str(
203 &mut self,
204 current: &Option<Vec<&'a Value>>,
205 values: Option<Box<dyn ExactSizeIterator<Item = &'a Value> + 'a>>,
206 key: &str,
207 ) {
208 self.filter(
209 current,
210 values,
211 |vec, tmp, not_matched| {
212 let mut visited = HashSet::new();
213 for (idx, v) in vec.iter().enumerate() {
214 match v {
215 Value::Object(map) => {
216 if map.contains_key(key) {
217 let ptr = *v as *const Value;
218 if !visited.contains(&ptr) {
219 visited.insert(ptr);
220 tmp.push(v)
221 }
222 } else {
223 not_matched.insert(idx);
224 }
225 }
226 Value::Array(vec) => {
227 not_matched.insert(idx);
228 for v in vec {
229 JValueWalker::walk_dedup(v, tmp, key, &mut visited);
230 }
231 }
232 _ => {
233 not_matched.insert(idx);
234 }
235 }
236 }
237
238 FilterKey::String(key.to_owned())
239 },
240 |vec, tmp, not_matched| {
241 let mut visited = HashSet::new();
242 for (idx, v) in vec.iter().enumerate() {
243 not_matched.insert(idx);
244 JValueWalker::walk_dedup(v, tmp, key, &mut visited);
245 }
246
247 FilterKey::String(key.to_owned())
248 },
249 );
250
251 debug!("filter_next_with_str : {}, {:?}", key, self.0);
252 }
253
254 fn collect_next_with_num(
255 &mut self,
256 current: &Option<Vec<&'a Value>>,
257 values: Option<Box<dyn ExactSizeIterator<Item = &'a Value> + 'a>>,
258 index: f64,
259 ) -> (Option<Vec<&'a Value>>, Option<Vec<usize>>) {
260 fn _collect<'a>(tmp: &mut Vec<&'a Value>, vec: &'a [Value], index: f64) {
261 let index = abs_index(index as isize, vec.len());
262 if let Some(v) = vec.get(index) {
263 tmp.push(v);
264 }
265 }
266
267 if let Some(current) = current {
268 let mut tmp = Vec::new();
269 for c in current {
270 match c {
271 Value::Object(map) => {
272 for k in map.keys() {
273 if let Some(Value::Array(vec)) = map.get(k) {
274 _collect(&mut tmp, vec, index);
275 }
276 }
277 }
278 Value::Array(vec) => {
279 _collect(&mut tmp, vec, index);
280 }
281 _ => {}
282 }
283 }
284
285 if tmp.is_empty() {
286 self.0.pop();
287 return (Some(vec![]), None);
288 } else {
289 return (Some(tmp), None);
290 }
291 }
292
293 if let Some(mut values) = values {
294 let index = abs_index(index as isize, values.len());
295
296 match values.nth(index) {
297 Some(value) => return (Some(vec![value]), Some(vec![index])),
298 None => {
299 self.0.pop();
300 return (Some(vec![]), None);
301 }
302 }
303 }
304
305 debug!("collect_next_with_num : {:?}, {:?}", &index, ¤t);
306
307 (None, None)
308 }
309
310 fn collect_next_all(
311 &mut self,
312 current: &Option<Vec<&'a Value>>,
313 values: Option<Box<dyn ExactSizeIterator<Item = &'a Value> + 'a>>,
314 ) -> (Option<Vec<&'a Value>>, Option<Vec<usize>>) {
315 if let Some(current) = current {
316 let mut tmp = Vec::new();
317 for c in current {
318 match c {
319 Value::Object(map) => {
320 for (_, v) in map {
321 tmp.push(v)
322 }
323 }
324 Value::Array(vec) => {
325 for v in vec {
326 tmp.push(v);
327 }
328 }
329 _ => {}
330 }
331 }
332 return (Some(tmp), None);
333 }
334
335 if let Some(current) = values {
336 let values = current.collect::<Vec<_>>();
337
338 let values_len = values.len();
339 return (Some(values), Some((0..values_len).collect()));
340 }
341
342 debug!("collect_next_all : {:?}", ¤t);
343
344 (None, None)
345 }
346
347 fn collect_next_with_str(
348 &mut self,
349 current: &Option<Vec<&'a Value>>,
350 values: Option<Box<dyn ExactSizeIterator<Item = &'a Value> + 'a>>,
351 keys: &[String],
352 ) -> (Option<Vec<&'a Value>>, Option<Vec<usize>>) {
353 if let Some(current) = current {
354 let mut tmp = Vec::new();
355 for c in current {
356 if let Value::Object(map) = c {
357 for key in keys {
358 if let Some(v) = map.get(key) {
359 tmp.push(v)
360 }
361 }
362 }
363 }
364
365 if tmp.is_empty() {
366 self.0.pop();
367 return (Some(vec![]), None);
368 } else {
369 return (Some(tmp), None);
370 }
371 }
372
373 if values.is_some() {
374 self.0.pop();
376 return (Some(vec![]), None);
377 }
378
379 debug!("collect_next_with_str : {:?}, {:?}", keys, ¤t);
380
381 (None, None)
382 }
383
384 fn collect_all(
385 &mut self,
386 current: &Option<Vec<&'a Value>>,
387 values: Option<Box<dyn ExactSizeIterator<Item = &'a Value> + 'a>>,
388 ) -> (Option<Vec<&'a Value>>, Option<Vec<usize>>) {
389 if let Some(current) = current {
390 let mut tmp = Vec::new();
391 JValueWalker::all(¤t, &mut tmp);
392 return (Some(tmp), None);
393 }
394
395 if let Some(values) = values {
396 let values = values.collect::<Vec<_>>();
397 let values_len = values.len();
398 return (Some(values), Some((0..values_len).collect()));
399 }
400 debug!("collect_all: {:?}", ¤t);
401
402 (None, None)
403 }
404
405 fn collect_all_with_str(
406 &mut self,
407 current: &Option<Vec<&'a Value>>,
408 values: Option<Box<dyn ExactSizeIterator<Item = &'a Value> + 'a>>,
409 key: &str,
410 ) -> (Option<Vec<&'a Value>>, Option<Vec<usize>>) {
411 if let Some(current) = current {
412 let mut tmp = Vec::new();
413 JValueWalker::all_with_str(¤t, &mut tmp, key, false);
414 return (Some(tmp), None);
415 }
416
417 if values.is_some() {
418 return (Some(vec![]), None);
419 }
420
421 debug!("collect_all_with_str: {}, {:?}", key, ¤t);
422
423 (None, None)
424 }
425
426 fn collect_all_with_num(
427 &mut self,
428 current: &Option<Vec<&'a Value>>,
429 values: Option<Box<dyn ExactSizeIterator<Item = &'a Value> + 'a>>,
430 index: f64,
431 ) -> (Option<Vec<&'a Value>>, Option<Vec<usize>>) {
432 if let Some(current) = current {
433 let mut tmp = Vec::new();
434 JValueWalker::all_with_num(¤t, &mut tmp, index);
435 return (Some(tmp), None);
436 }
437
438 if let Some(mut values) = values {
439 match values.nth(index as usize) {
440 Some(value) => return (Some(vec![value]), Some(vec![index as usize])),
441 None => return (Some(vec![]), None),
442 }
443 }
444
445 debug!("collect_all_with_num: {}, {:?}", index, ¤t);
446
447 (None, None)
448 }
449}
450
451#[derive(Default)]
452pub struct Selector<'a, 'b> {
453 node: Option<Node>,
454 node_ref: Option<&'b Node>,
455 value: Option<&'a Value>,
456 tokens: Vec<ParseToken>,
457 current: Option<Vec<&'a Value>>,
458 values: Option<Box<dyn ExactSizeIterator<Item = &'a Value> + 'a>>,
459 chose_indices: Vec<usize>,
460 not_found_by_key_index: bool,
462 selectors: Vec<Selector<'a, 'b>>,
463 selector_filter: FilterTerms<'a>,
464}
465
466impl<'a, 'b> Selector<'a, 'b> {
467 pub fn new() -> Self {
468 Self::default()
469 }
470
471 pub fn str_path(&mut self, path: &str) -> Result<&mut Self, JsonPathError> {
472 debug!("path : {}", path);
473
474 self.node_ref.take();
475 self.node = Some(Parser::compile(path).map_err(JsonPathError::Path)?);
476 Ok(self)
477 }
478
479 pub fn node_ref(&self) -> Option<&Node> {
480 if let Some(node) = &self.node {
481 return Some(node);
482 }
483
484 if let Some(node) = &self.node_ref {
485 return Some(*node);
486 }
487
488 None
489 }
490
491 pub fn compiled_path(&mut self, node: &'b Node) -> &mut Self {
492 self.node.take();
493 self.node_ref = Some(node);
494 self
495 }
496
497 pub fn reset_value(&mut self) -> &mut Self {
498 self.current = None;
499 self
500 }
501
502 pub fn value(&mut self, v: &'a Value) -> &mut Self {
503 self.value = Some(v);
504 self
505 }
506
507 pub fn values_iter(
508 &mut self,
509 values: impl Iterator<Item = &'a Value> + ExactSizeIterator + 'a,
510 ) -> &mut Self {
511 self.values = Some(Box::new(values));
512 self
513 }
514
515 fn _select(&mut self) -> Result<(), JsonPathError> {
516 if self.node_ref.is_some() {
517 let node_ref = self.node_ref.take().unwrap();
518 self.visit(node_ref);
519
520 return if self.not_found_by_key_index {
521 Err(JsonPathError::EmptyValue)
522 } else {
523 Ok(())
524 };
525 }
526
527 if self.node.is_none() {
528 return Err(JsonPathError::EmptyPath);
529 }
530
531 let node = self.node.take().unwrap();
532 self.visit(&node);
533 self.node = Some(node);
534
535 if self.not_found_by_key_index {
536 Err(JsonPathError::EmptyValue)
537 } else {
538 Ok(())
539 }
540 }
541
542 pub fn select_as<T: serde::de::DeserializeOwned>(&mut self) -> Result<Vec<T>, JsonPathError> {
543 self._select()?;
544
545 match &self.current {
546 Some(vec) => {
547 let mut ret = Vec::new();
548 for v in vec {
549 match T::deserialize(*v) {
550 Ok(v) => ret.push(v),
551 Err(e) => return Err(JsonPathError::Serde(e.to_string())),
552 }
553 }
554 Ok(ret)
555 }
556 _ => Err(JsonPathError::EmptyValue),
557 }
558 }
559
560 pub fn select_as_str(&mut self) -> Result<String, JsonPathError> {
561 self._select()?;
562
563 match &self.current {
564 Some(r) => {
565 Ok(serde_json::to_string(r).map_err(|e| JsonPathError::Serde(e.to_string()))?)
566 }
567 _ => Err(JsonPathError::EmptyValue),
568 }
569 }
570
571 pub fn select(&mut self) -> Result<Vec<&'a Value>, JsonPathError> {
572 self._select()?;
573
574 match &self.current {
575 Some(r) => Ok(r.to_vec()),
576 _ => Err(JsonPathError::EmptyValue),
577 }
578 }
579
580 pub fn select_(&mut self) -> Result<Vec<&'a Value>, JsonPathError> {
581 self._select()?;
582
583 match &self.current {
584 Some(r) => Ok(r.to_vec()),
585 _ => Err(JsonPathError::EmptyValue),
586 }
587 }
588
589 fn compute_absolute_path_filter(&mut self, token: &ParseToken) -> bool {
590 if !self.selectors.is_empty() {
591 match token {
592 ParseToken::Absolute | ParseToken::Relative | ParseToken::Filter(_) => {
593 let selector = self.selectors.pop().unwrap();
594
595 if let Some(current) = &selector.current {
596 let term = current.into();
597
598 if let Some(s) = self.selectors.last_mut() {
599 s.selector_filter.push_term(Some(term));
600 } else {
601 self.selector_filter.push_term(Some(term));
602 }
603 } else {
604 unreachable!()
605 }
606 }
607 _ => {}
608 }
609 }
610
611 if let Some(selector) = self.selectors.last_mut() {
612 selector.visit_token(token);
613 true
614 } else {
615 false
616 }
617 }
618}
619
620impl<'a, 'b> Selector<'a, 'b> {
621 fn visit_absolute(&mut self) {
622 if self.current.is_some() {
623 let mut selector = Selector::default();
624
625 if let Some(value) = self.value {
626 selector.value = Some(value);
627 selector.current = Some(vec![value]);
628
629 println!("current.is_some: {:?}", selector.current);
630 self.selectors.push(selector);
631 }
632 return;
633 }
634
635 if self.values.is_some() {
636 return;
637 }
638
639 if let Some(v) = &self.value {
640 self.current = Some(vec![v]);
641 }
642 }
643
644 fn visit_relative(&mut self) {
645 if let Some(ParseToken::Array) = self.tokens.last() {
646 let array_token = self.tokens.pop();
647 if let Some(ParseToken::Leaves) = self.tokens.last() {
648 let values = std::mem::replace(&mut self.values, None);
649 self.tokens.pop();
650 let (current, chose_indices) =
651 self.selector_filter.collect_all(&self.current, values);
652
653 self.current = current;
654 self.update_not_found_by_current();
655
656 self.chose_indices.extend(chose_indices.unwrap_or_default());
657 }
658 self.tokens.push(array_token.unwrap());
659 }
660 self.selector_filter.new_filter_context();
661 }
662
663 fn visit_array_eof(&mut self) {
664 if self.is_last_before_token_match(ParseToken::Array) {
665 if let Some(Some(e)) = self.selector_filter.pop_term() {
666 let values = std::mem::replace(&mut self.values, None);
667 if let ExprTerm::String(key) = e {
668 self.selector_filter
669 .filter_next_with_str(&self.current, values, &key);
670 self.tokens.pop();
671 return;
672 }
673
674 self.selector_filter.push_term(Some(e));
675 }
676 }
677
678 if self.is_last_before_token_match(ParseToken::Leaves) {
679 self.tokens.pop();
680 self.tokens.pop();
681 if let Some(Some(e)) = self.selector_filter.pop_term() {
682 let selector_filter_consumed =
683 match &e {
684 ExprTerm::Number(n) => {
685 let values = std::mem::replace(&mut self.values, None);
686 let (current, chose_indices) = self
687 .selector_filter
688 .collect_all_with_num(&self.current, values, to_f64(n));
689
690 self.selector_filter.pop_term();
691
692 self.current = current;
693 self.update_not_found_by_current();
694
695 self.chose_indices.extend(chose_indices.unwrap_or_default());
696 true
697 }
698 ExprTerm::String(key) => {
699 let values = std::mem::replace(&mut self.values, None);
700 let (current, chose_indices) = self
701 .selector_filter
702 .collect_all_with_str(&self.current, values, key);
703
704 self.selector_filter.pop_term();
705 self.current = current;
706 self.update_not_found_by_current();
707
708 self.chose_indices.extend(chose_indices.unwrap_or_default());
709 true
710 }
711 _ => {
712 self.selector_filter.push_term(Some(e));
713 false
714 }
715 };
716
717 if selector_filter_consumed {
718 return;
719 }
720 }
721 }
722
723 if let Some(Some(e)) = self.selector_filter.pop_term() {
724 match e {
725 ExprTerm::Number(n) => {
726 let values = std::mem::replace(&mut self.values, None);
727 let (current, chose_indices) = self.selector_filter.collect_next_with_num(
728 &self.current,
729 values,
730 to_f64(&n),
731 );
732
733 self.current = current;
734 self.update_not_found_by_current();
735
736 self.chose_indices.extend(chose_indices.unwrap_or_default());
737 }
738 ExprTerm::String(key) => {
739 let values = std::mem::replace(&mut self.values, None);
740
741 let (current, chose_indices) =
742 self.selector_filter
743 .collect_next_with_str(&self.current, values, &[key]);
744
745 self.current = current;
746 self.update_not_found_by_current();
747
748 self.chose_indices.extend(chose_indices.unwrap_or_default());
749 }
750 ExprTerm::Json(rel, _, v) => {
751 if v.is_empty() {
752 self.current = Some(vec![]);
753 } else if let Some(vec) = rel {
754 self.current = Some(vec);
755 } else {
756 self.current = Some(v);
757 }
758
759 self.update_not_found_by_current();
760 }
761 ExprTerm::Bool(false) => {
762 self.current = Some(vec![]);
763 }
764 _ => {}
765 }
766 }
767
768 self.tokens.pop();
769 }
770
771 fn is_last_before_token_match(&mut self, token: ParseToken) -> bool {
772 if self.tokens.len() > 1 {
773 return token == self.tokens[self.tokens.len() - 2];
774 }
775
776 false
777 }
778
779 fn visit_all(&mut self) {
780 if let Some(ParseToken::Array) = self.tokens.last() {
781 self.tokens.pop();
782 }
783
784 let values = std::mem::replace(&mut self.values, None);
785 match self.tokens.last() {
786 Some(ParseToken::Leaves) => {
787 self.tokens.pop();
788 let (current, chose_indices) =
789 self.selector_filter.collect_all(&self.current, values);
790
791 self.current = current;
792 self.chose_indices.extend(chose_indices.unwrap_or_default());
793 }
794 Some(ParseToken::In) => {
795 self.tokens.pop();
796 let (current, chose_indices) =
797 self.selector_filter.collect_next_all(&self.current, values);
798
799 self.current = current;
800 self.chose_indices.extend(chose_indices.unwrap_or_default());
801 }
802 _ => {
803 let (current, chose_indices) =
804 self.selector_filter.collect_next_all(&self.current, values);
805
806 self.current = current;
807 self.chose_indices.extend(chose_indices.unwrap_or_default());
808 }
809 }
810 }
811
812 fn visit_key(&mut self, key: &str) {
813 if let Some(ParseToken::Array) = self.tokens.last() {
814 self.selector_filter
815 .push_term(Some(ExprTerm::String(key.to_string())));
816 return;
817 }
818
819 if let Some(t) = self.tokens.pop() {
820 if self.selector_filter.is_term_empty() {
821 match t {
822 ParseToken::Leaves => {
823 let values = std::mem::replace(&mut self.values, None);
824 let (current, chose_indices) =
825 self.selector_filter
826 .collect_all_with_str(&self.current, values, key);
827
828 self.current = current;
829 self.chose_indices.extend(chose_indices.unwrap_or_default());
830 }
831 ParseToken::In => {
832 let values = std::mem::replace(&mut self.values, None);
833 let (current, chose_indices) = self.selector_filter.collect_next_with_str(
834 &self.current,
835 values,
836 &[key.to_string()],
837 );
838
839 self.current = current;
840 self.update_not_found_by_current();
841
842 self.chose_indices.extend(chose_indices.unwrap_or_default());
843 }
844 _ => {}
845 }
846 } else {
847 match t {
848 ParseToken::Leaves => {
849 let values = std::mem::replace(&mut self.values, None);
850 self.selector_filter
851 .filter_all_with_str(&self.current, values, key);
852 }
853 ParseToken::In => {
854 let values = std::mem::replace(&mut self.values, None);
855 self.selector_filter
856 .filter_next_with_str(&self.current, values, key);
857 }
858 _ => {}
859 }
860 }
861 }
862 }
863
864 fn visit_keys(&mut self, keys: &[String]) {
865 if !self.selector_filter.is_term_empty() {
866 unimplemented!("keys in filter");
867 }
868
869 if let Some(ParseToken::Array) = self.tokens.pop() {
870 let values = std::mem::replace(&mut self.values, None);
871 let (current, chose_indices) =
872 self.selector_filter
873 .collect_next_with_str(&self.current, values, keys);
874 self.current = current;
875 self.update_not_found_by_current();
876
877 self.chose_indices.extend(chose_indices.unwrap_or_default());
878 } else {
879 unreachable!();
880 }
881 }
882
883 fn visit_filter(&mut self, ft: &FilterToken) {
884 let right = match self.selector_filter.pop_term() {
885 Some(Some(right)) => right,
886 Some(None) => ExprTerm::Json(
887 None,
888 None,
889 match &self.current {
890 Some(current) => current.to_vec(),
891 _ => unreachable!(),
892 },
893 ),
894 _ => panic!("empty term right"),
895 };
896
897 let left = match self.selector_filter.pop_term() {
898 Some(Some(left)) => left,
899 Some(None) => ExprTerm::Json(
900 None,
901 None,
902 match &self.current {
903 Some(current) => current.to_vec(),
904 _ => unreachable!(),
905 },
906 ),
907 _ => panic!("empty term left"),
908 };
909
910 let mut ret = None;
911 match ft {
912 FilterToken::Equal => left.eq(&right, &mut ret),
913 FilterToken::NotEqual => left.ne(&right, &mut ret),
914 FilterToken::Greater => left.gt(&right, &mut ret),
915 FilterToken::GreaterOrEqual => left.ge(&right, &mut ret),
916 FilterToken::Little => left.lt(&right, &mut ret),
917 FilterToken::LittleOrEqual => left.le(&right, &mut ret),
918 FilterToken::And => left.and(&right, &mut ret),
919 FilterToken::Or => left.or(&right, &mut ret),
920 };
921
922 if let Some(e) = ret {
923 self.selector_filter.push_term(Some(e));
924 }
925 }
926
927 fn visit_range(&mut self, from: &Option<isize>, to: &Option<isize>, step: &Option<usize>) {
928 if !self.selector_filter.is_term_empty() {
929 unimplemented!("range syntax in filter");
930 }
931
932 if let Some(ParseToken::Array) = self.tokens.pop() {
933 let mut tmp = Vec::new();
934 if let Some(current) = &self.current {
935 for v in current {
936 if let Value::Array(vec) = v {
937 let from = match from {
938 Some(from) => abs_index(*from, vec.len()),
939 None => 0,
940 };
941
942 let to = match to {
943 Some(to) => abs_index(*to, vec.len()),
944 None => vec.len(),
945 };
946
947 let step = match step {
948 Some(step) => *step,
949 None => 1,
950 };
951
952 for i in (from..to).step_by(step) {
953 if let Some(v) = vec.get(i) {
954 tmp.push(v);
955 }
956 }
957 }
958 }
959 } else {
960 let values = std::mem::replace(&mut self.values, None);
961 if let Some(values) = values {
962 let from = match from {
963 Some(from) => abs_index(*from, values.len()),
964 None => 0,
965 };
966
967 let to = match to {
968 Some(to) => abs_index(*to, values.len()),
969 None => values.len(),
970 };
971
972 let step = match step {
973 Some(step) => *step,
974 None => 1,
975 };
976
977 let take_count = if from > to { 0 } else { to - from };
978
979 let matched_values = values.skip(from).step_by(step).take(take_count);
980 tmp.extend(matched_values);
981
982 self.chose_indices
983 .extend((from..to).step_by(step).collect::<Vec<_>>())
984 }
985 }
986 self.current = Some(tmp);
987 } else {
988 unreachable!();
989 }
990 }
991
992 fn visit_union(&mut self, indices: &[isize]) {
993 if !self.selector_filter.is_term_empty() {
994 unimplemented!("union syntax in filter");
995 }
996
997 if let Some(ParseToken::Array) = self.tokens.pop() {
998 let mut tmp = Vec::new();
999 if let Some(current) = &self.current {
1000 for v in current {
1001 if let Value::Array(vec) = v {
1002 for i in indices {
1003 if let Some(v) = vec.get(abs_index(*i, vec.len())) {
1004 tmp.push(v);
1005 }
1006 }
1007 }
1008 }
1009 } else {
1010 let indices = indices.iter().map(|&v| v as usize).collect::<HashSet<_>>();
1011 let values = std::mem::replace(&mut self.values, None);
1012 if let Some(values) = values {
1013 let new_values = values
1014 .enumerate()
1015 .filter(|(id, _)| indices.contains(id))
1016 .map(|(id, value)| {
1017 self.chose_indices.push(id);
1018 value
1019 })
1020 .collect::<Vec<_>>();
1021
1022 tmp.extend(new_values);
1023 }
1024 }
1025
1026 self.current = Some(tmp);
1027 } else {
1028 unreachable!();
1029 }
1030 }
1031
1032 fn update_not_found_by_current(&mut self) {
1033 if let Some(values) = &self.current {
1034 self.not_found_by_key_index |= values.is_empty();
1035 }
1036 }
1037
1038 pub fn chose_indices(self) -> Vec<usize> {
1039 self.chose_indices
1040 }
1041}
1042
1043impl<'a, 'b> NodeVisitor for Selector<'a, 'b> {
1044 fn visit_token(&mut self, token: &ParseToken) {
1045 debug!("token: {:?}, stack: {:?}", token, self.tokens);
1046
1047 if self.compute_absolute_path_filter(token) {
1048 return;
1049 }
1050
1051 match token {
1052 ParseToken::Absolute => self.visit_absolute(),
1053 ParseToken::Relative => self.visit_relative(),
1054 ParseToken::In | ParseToken::Leaves | ParseToken::Array => {
1055 self.tokens.push(token.clone());
1056 }
1057 ParseToken::ArrayEof => self.visit_array_eof(),
1058 ParseToken::All => self.visit_all(),
1059 ParseToken::Bool(b) => {
1060 self.selector_filter.push_term(Some(ExprTerm::Bool(*b)));
1061 }
1062 ParseToken::Key(key) => self.visit_key(key),
1063 ParseToken::Keys(keys) => self.visit_keys(keys),
1064 ParseToken::Number(v) => {
1065 self.selector_filter
1066 .push_term(Some(ExprTerm::Number(Number::from_f64(*v).unwrap())));
1067 }
1068 ParseToken::Filter(ref ft) => self.visit_filter(ft),
1069 ParseToken::Range(from, to, step) => self.visit_range(from, to, step),
1070 ParseToken::Union(indices) => self.visit_union(indices),
1071 ParseToken::Eof => {
1072 debug!("visit_token eof");
1073 }
1074 }
1075 }
1076}
1077
1078#[derive(Default)]
1079pub struct SelectorMut {
1080 path: Option<Node>,
1081 value: Option<Value>,
1082}
1083
1084fn replace_value<F: FnMut(Value) -> Option<Value>>(
1085 mut tokens: Vec<String>,
1086 value: &mut Value,
1087 fun: &mut F,
1088) {
1089 let mut target = value;
1090
1091 let last_index = tokens.len().saturating_sub(1);
1092 for (i, token) in tokens.drain(..).enumerate() {
1093 let target_once = target;
1094 let is_last = i == last_index;
1095 let target_opt = match *target_once {
1096 Value::Object(ref mut map) => {
1097 if is_last {
1098 if let Entry::Occupied(mut e) = map.entry(token) {
1099 let v = e.insert(Value::Null);
1100 if let Some(res) = fun(v) {
1101 e.insert(res);
1102 } else {
1103 e.remove();
1104 }
1105 }
1106 return;
1107 }
1108 map.get_mut(&token)
1109 }
1110 Value::Array(ref mut vec) => {
1111 if let Ok(x) = token.parse::<usize>() {
1112 if is_last {
1113 let v = std::mem::replace(&mut vec[x], Value::Null);
1114 if let Some(res) = fun(v) {
1115 vec[x] = res;
1116 } else {
1117 vec.remove(x);
1118 }
1119 return;
1120 }
1121 vec.get_mut(x)
1122 } else {
1123 None
1124 }
1125 }
1126 _ => None,
1127 };
1128
1129 if let Some(t) = target_opt {
1130 target = t;
1131 } else {
1132 break;
1133 }
1134 }
1135}
1136
1137impl SelectorMut {
1138 pub fn new() -> Self {
1139 Self::default()
1140 }
1141
1142 pub fn str_path(&mut self, path: &str) -> Result<&mut Self, JsonPathError> {
1143 self.path = Some(Parser::compile(path).map_err(JsonPathError::Path)?);
1144 Ok(self)
1145 }
1146
1147 pub fn value(&mut self, value: Value) -> &mut Self {
1148 self.value = Some(value);
1149 self
1150 }
1151
1152 pub fn take(&mut self) -> Option<Value> {
1153 self.value.take()
1154 }
1155
1156 fn compute_paths(&self, mut result: Vec<&Value>) -> Vec<Vec<String>> {
1157 fn _walk(
1158 origin: &Value,
1159 target: &mut Vec<&Value>,
1160 tokens: &mut Vec<String>,
1161 visited: &mut HashSet<*const Value>,
1162 visited_order: &mut Vec<Vec<String>>,
1163 ) -> bool {
1164 trace!("{:?}, {:?}", target, tokens);
1165
1166 if target.is_empty() {
1167 return true;
1168 }
1169
1170 target.retain(|t| {
1171 if std::ptr::eq(origin, *t) {
1172 if visited.insert(*t) {
1173 visited_order.push(tokens.to_vec());
1174 }
1175 false
1176 } else {
1177 true
1178 }
1179 });
1180
1181 match origin {
1182 Value::Array(vec) => {
1183 for (i, v) in vec.iter().enumerate() {
1184 tokens.push(i.to_string());
1185 if _walk(v, target, tokens, visited, visited_order) {
1186 return true;
1187 }
1188 tokens.pop();
1189 }
1190 }
1191 Value::Object(map) => {
1192 for (k, v) in map {
1193 tokens.push(k.clone());
1194 if _walk(v, target, tokens, visited, visited_order) {
1195 return true;
1196 }
1197 tokens.pop();
1198 }
1199 }
1200 _ => {}
1201 }
1202
1203 false
1204 }
1205
1206 let mut visited = HashSet::new();
1207 let mut visited_order = Vec::new();
1208
1209 if let Some(origin) = &self.value {
1210 let mut tokens = Vec::new();
1211 _walk(
1212 origin,
1213 &mut result,
1214 &mut tokens,
1215 &mut visited,
1216 &mut visited_order,
1217 );
1218 }
1219
1220 visited_order
1221 }
1222
1223 pub fn delete(&mut self) -> Result<&mut Self, JsonPathError> {
1224 self.replace_with(&mut |_| Some(Value::Null))
1225 }
1226
1227 pub fn remove(&mut self) -> Result<&mut Self, JsonPathError> {
1228 self.replace_with(&mut |_| None)
1229 }
1230
1231 fn select(&self) -> Result<Vec<&Value>, JsonPathError> {
1232 if let Some(node) = &self.path {
1233 let mut selector = Selector::default();
1234 selector.compiled_path(&node);
1235
1236 if let Some(value) = &self.value {
1237 selector.value(value);
1238 }
1239
1240 Ok(selector.select()?)
1241 } else {
1242 Err(JsonPathError::EmptyPath)
1243 }
1244 }
1245
1246 pub fn replace_with<F: FnMut(Value) -> Option<Value>>(
1247 &mut self,
1248 fun: &mut F,
1249 ) -> Result<&mut Self, JsonPathError> {
1250 let paths = {
1251 let result = self.select()?;
1252 self.compute_paths(result)
1253 };
1254
1255 if let Some(ref mut value) = &mut self.value {
1256 for tokens in paths {
1257 replace_value(tokens, value, fun);
1258 }
1259 }
1260
1261 Ok(self)
1262 }
1263}
1264
1265#[cfg(test)]
1266mod select_inner_tests {
1267 use serde_json::Value;
1268
1269 #[test]
1270 fn to_f64_i64() {
1271 let number = 0_i64;
1272 let v: Value = serde_json::from_str(&format!("{}", number)).unwrap();
1273 if let Value::Number(n) = v {
1274 assert_eq!((super::to_f64(&n) - number as f64).abs() == 0_f64, true);
1275 } else {
1276 panic!();
1277 }
1278 }
1279
1280 #[test]
1281 fn to_f64_f64() {
1282 let number = 0.1_f64;
1283 let v: Value = serde_json::from_str(&format!("{}", number)).unwrap();
1284 if let Value::Number(n) = v {
1285 assert_eq!((super::to_f64(&n) - number).abs() == 0_f64, true);
1286 } else {
1287 panic!();
1288 }
1289 }
1290
1291 #[test]
1292 fn to_f64_u64() {
1293 let number = u64::max_value();
1294 let v: Value = serde_json::from_str(&format!("{}", number)).unwrap();
1295 if let Value::Number(n) = v {
1296 assert_eq!((super::to_f64(&n) - number as f64).abs() == 0_f64, true);
1297 } else {
1298 panic!();
1299 }
1300 }
1301}