jsonpath_lib/select/
mod.rs

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: {:?}", &current);
145
146        if let Some(current) = &current {
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, &current);
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 : {:?}", &current);
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            // values has array-like structure
375            self.0.pop();
376            return (Some(vec![]), None);
377        }
378
379        debug!("collect_next_with_str : {:?}, {:?}", keys, &current);
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(&current, &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: {:?}", &current);
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(&current, &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, &current);
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(&current, &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, &current);
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    // true if values haven't been found by key or index in JValue
461    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}