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 crate::{debug, parser::*, trace};
8
9use self::expr_term::*;
10use self::value_walker::ValueWalker;
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    Path(String),
44    Serde(String),
45}
46
47impl std::error::Error for JsonPathError {}
48
49impl fmt::Debug for JsonPathError {
50    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
51        write!(f, "{}", self)
52    }
53}
54
55impl fmt::Display for JsonPathError {
56    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
57        match self {
58            JsonPathError::EmptyPath => f.write_str("path not set"),
59            JsonPathError::EmptyValue => f.write_str("json value not set"),
60            JsonPathError::Path(msg) => f.write_str(&format!("path error: \n{}\n", msg)),
61            JsonPathError::Serde(msg) => f.write_str(&format!("serde error: \n{}\n", msg)),
62        }
63    }
64}
65
66#[derive(Debug, Default)]
67struct FilterTerms<'a>(Vec<Option<ExprTerm<'a>>>);
68
69impl<'a> FilterTerms<'a> {
70    fn new_filter_context(&mut self) {
71        self.0.push(None);
72        debug!("new_filter_context: {:?}", self.0);
73    }
74
75    fn is_term_empty(&self) -> bool {
76        self.0.is_empty()
77    }
78
79    fn push_term(&mut self, term: Option<ExprTerm<'a>>) {
80        self.0.push(term);
81    }
82
83    #[allow(clippy::option_option)]
84    fn pop_term(&mut self) -> Option<Option<ExprTerm<'a>>> {
85        self.0.pop()
86    }
87
88    fn filter_json_term<
89        F: Fn(&Vec<&'a Value>, &mut Vec<&'a Value>, &mut HashSet<usize>) -> FilterKey,
90    >(
91        &mut self,
92        e: ExprTerm<'a>,
93        fun: F,
94    ) {
95        debug!("filter_json_term: {:?}", e);
96
97        if let ExprTerm::Json(rel, fk, vec) = e {
98            let mut tmp = Vec::new();
99            let mut not_matched = HashSet::new();
100            let filter_key = if let Some(FilterKey::String(key)) = fk {
101                let key_contained = &vec
102                    .iter()
103                    .map(|v| match v {
104                        Value::Object(map) if map.contains_key(&key) => map.get(&key).unwrap(),
105                        _ => v,
106                    })
107                    .collect();
108                fun(key_contained, &mut tmp, &mut not_matched)
109            } else {
110                fun(&vec, &mut tmp, &mut not_matched)
111            };
112
113            if rel.is_some() {
114                self.0
115                    .push(Some(ExprTerm::Json(rel, Some(filter_key), tmp)));
116            } else {
117                let filtered: Vec<&Value> = vec
118                    .iter()
119                    .enumerate()
120                    .filter(|(idx, _)| !not_matched.contains(idx))
121                    .map(|(_, v)| *v)
122                    .collect();
123
124                self.0
125                    .push(Some(ExprTerm::Json(Some(filtered), Some(filter_key), tmp)));
126            }
127        } else {
128            unreachable!("unexpected: ExprTerm: {:?}", e);
129        }
130    }
131
132    fn push_json_term<
133        F: Fn(&Vec<&'a Value>, &mut Vec<&'a Value>, &mut HashSet<usize>) -> FilterKey,
134    >(
135        &mut self,
136        current: &Option<Vec<&'a Value>>,
137        fun: F,
138    ) {
139        debug!("push_json_term: {:?}", &current);
140
141        if let Some(current) = &current {
142            let mut tmp = Vec::new();
143            let mut not_matched = HashSet::new();
144            let filter_key = fun(current, &mut tmp, &mut not_matched);
145            self.0
146                .push(Some(ExprTerm::Json(None, Some(filter_key), tmp)));
147        }
148    }
149
150    fn filter<F: Fn(&Vec<&'a Value>, &mut Vec<&'a Value>, &mut HashSet<usize>) -> FilterKey>(
151        &mut self,
152        current: &Option<Vec<&'a Value>>,
153        fun: F,
154    ) {
155        if let Some(peek) = self.0.pop() {
156            if let Some(e) = peek {
157                self.filter_json_term(e, fun);
158            } else {
159                self.push_json_term(current, fun);
160            }
161        }
162    }
163
164    fn filter_all_with_str(&mut self, current: &Option<Vec<&'a Value>>, key: &str) {
165        self.filter(current, |vec, tmp, _| {
166            ValueWalker::all_with_str(vec, tmp, key, true);
167            FilterKey::All
168        });
169
170        debug!("filter_all_with_str : {}, {:?}", key, self.0);
171    }
172
173    fn filter_next_with_str(&mut self, current: &Option<Vec<&'a Value>>, key: &str) {
174        self.filter(current, |vec, tmp, not_matched| {
175            let mut visited = HashSet::new();
176            for (idx, v) in vec.iter().enumerate() {
177                match v {
178                    Value::Object(map) => {
179                        if map.contains_key(key) {
180                            let ptr = *v as *const Value;
181                            if !visited.contains(&ptr) {
182                                visited.insert(ptr);
183                                tmp.push(v)
184                            }
185                        } else {
186                            not_matched.insert(idx);
187                        }
188                    }
189                    Value::Array(vec) => {
190                        not_matched.insert(idx);
191                        for v in vec {
192                            ValueWalker::walk_dedup(v, tmp, key, &mut visited);
193                        }
194                    }
195                    _ => {
196                        not_matched.insert(idx);
197                    }
198                }
199            }
200
201            FilterKey::String(key.to_owned())
202        });
203
204        debug!("filter_next_with_str : {}, {:?}", key, self.0);
205    }
206
207    fn collect_next_with_num(
208        &mut self,
209        current: &Option<Vec<&'a Value>>,
210        index: f64,
211    ) -> Option<Vec<&'a Value>> {
212        fn _collect<'a>(tmp: &mut Vec<&'a Value>, vec: &'a [Value], index: f64) {
213            let index = abs_index(index as isize, vec.len());
214            if let Some(v) = vec.get(index) {
215                tmp.push(v);
216            }
217        }
218
219        if let Some(current) = current {
220            let mut tmp = Vec::new();
221            for c in current {
222                match c {
223                    Value::Object(map) => {
224                        for k in map.keys() {
225                            if let Some(Value::Array(vec)) = map.get(k) {
226                                _collect(&mut tmp, vec, index);
227                            }
228                        }
229                    }
230                    Value::Array(vec) => {
231                        _collect(&mut tmp, vec, index);
232                    }
233                    _ => {}
234                }
235            }
236
237            if tmp.is_empty() {
238                self.0.pop();
239                return Some(vec![]);
240            } else {
241                return Some(tmp);
242            }
243        }
244
245        debug!("collect_next_with_num : {:?}, {:?}", &index, &current);
246
247        None
248    }
249
250    fn collect_next_all(&mut self, current: &Option<Vec<&'a Value>>) -> Option<Vec<&'a Value>> {
251        if let Some(current) = current {
252            let mut tmp = Vec::new();
253            for c in current {
254                match c {
255                    Value::Object(map) => {
256                        for (_, v) in map {
257                            tmp.push(v)
258                        }
259                    }
260                    Value::Array(vec) => {
261                        for v in vec {
262                            tmp.push(v);
263                        }
264                    }
265                    _ => {}
266                }
267            }
268            return Some(tmp);
269        }
270
271        debug!("collect_next_all : {:?}", &current);
272
273        None
274    }
275
276    fn collect_next_with_str(
277        &mut self,
278        current: &Option<Vec<&'a Value>>,
279        keys: &[String],
280    ) -> Option<Vec<&'a Value>> {
281        if let Some(current) = current {
282            let mut tmp = Vec::new();
283            for c in current {
284                if let Value::Object(map) = c {
285                    for key in keys {
286                        if let Some(v) = map.get(key) {
287                            tmp.push(v)
288                        }
289                    }
290                }
291            }
292
293            if tmp.is_empty() {
294                self.0.pop();
295                return Some(vec![]);
296            } else {
297                return Some(tmp);
298            }
299        }
300
301        debug!("collect_next_with_str : {:?}, {:?}", keys, &current);
302
303        None
304    }
305
306    fn collect_all(&mut self, current: &Option<Vec<&'a Value>>) -> Option<Vec<&'a Value>> {
307        if let Some(current) = current {
308            let mut tmp = Vec::new();
309            ValueWalker::all(current, &mut tmp);
310            return Some(tmp);
311        }
312        debug!("collect_all: {:?}", &current);
313
314        None
315    }
316
317    fn collect_all_with_str(
318        &mut self,
319        current: &Option<Vec<&'a Value>>,
320        key: &str,
321    ) -> Option<Vec<&'a Value>> {
322        if let Some(current) = current {
323            let mut tmp = Vec::new();
324            ValueWalker::all_with_str(current, &mut tmp, key, false);
325            return Some(tmp);
326        }
327
328        debug!("collect_all_with_str: {}, {:?}", key, &current);
329
330        None
331    }
332
333    fn collect_all_with_num(
334        &mut self,
335        current: &Option<Vec<&'a Value>>,
336        index: f64,
337    ) -> Option<Vec<&'a Value>> {
338        if let Some(current) = current {
339            let mut tmp = Vec::new();
340            ValueWalker::all_with_num(current, &mut tmp, index);
341            return Some(tmp);
342        }
343
344        debug!("collect_all_with_num: {}, {:?}", index, &current);
345
346        None
347    }
348}
349
350#[deprecated(since = "0.4.0", note = "Please use `JsonSelector`")]
351#[derive(Debug, Default)]
352pub struct Selector<'a, 'b> {
353    #[allow(deprecated)]
354    node: Option<Node>,
355    #[allow(deprecated)]
356    node_ref: Option<&'b Node>,
357    value: Option<&'a Value>,
358    tokens: Vec<ParseToken>,
359    current: Option<Vec<&'a Value>>,
360    #[allow(deprecated)]
361    selectors: Vec<Selector<'a, 'b>>,
362    selector_filter: FilterTerms<'a>,
363}
364
365#[allow(deprecated)]
366impl<'a, 'b> Selector<'a, 'b> {
367    pub fn new() -> Self {
368        Self::default()
369    }
370
371    pub fn str_path(&mut self, path: &str) -> Result<&mut Self, JsonPathError> {
372        debug!("path : {}", path);
373        self.node_ref.take();
374        self.node = Some(Parser::compile(path).map_err(JsonPathError::Path)?);
375        Ok(self)
376    }
377
378    pub fn node_ref(&self) -> Option<&Node> {
379        if let Some(node) = &self.node {
380            return Some(node);
381        }
382
383        if let Some(node) = &self.node_ref {
384            return Some(*node);
385        }
386
387        None
388    }
389
390    pub fn compiled_path(&mut self, node: &'b Node) -> &mut Self {
391        self.node.take();
392        self.node_ref = Some(node);
393        self
394    }
395
396    pub fn reset_value(&mut self) -> &mut Self {
397        self.current = None;
398        self
399    }
400
401    pub fn value(&mut self, v: &'a Value) -> &mut Self {
402        self.value = Some(v);
403        self
404    }
405
406    fn _select(&mut self) -> Result<(), JsonPathError> {
407        if self.node_ref.is_some() {
408            let node_ref = self.node_ref.take().unwrap();
409            self.visit(node_ref);
410            return Ok(());
411        }
412
413        if self.node.is_none() {
414            return Err(JsonPathError::EmptyPath);
415        }
416
417        let node = self.node.take().unwrap();
418        self.visit(&node);
419        self.node = Some(node);
420
421        Ok(())
422    }
423
424    pub fn select_as<T: serde::de::DeserializeOwned>(&mut self) -> Result<Vec<T>, JsonPathError> {
425        self._select()?;
426
427        match &self.current {
428            Some(vec) => {
429                let mut ret = Vec::new();
430                for v in vec {
431                    match T::deserialize(*v) {
432                        Ok(v) => ret.push(v),
433                        Err(e) => return Err(JsonPathError::Serde(e.to_string())),
434                    }
435                }
436                Ok(ret)
437            }
438            _ => Err(JsonPathError::EmptyValue),
439        }
440    }
441
442    pub fn select_as_str(&mut self) -> Result<String, JsonPathError> {
443        self._select()?;
444
445        match &self.current {
446            Some(r) => {
447                Ok(serde_json::to_string(r).map_err(|e| JsonPathError::Serde(e.to_string()))?)
448            }
449            _ => Err(JsonPathError::EmptyValue),
450        }
451    }
452
453    pub fn select(&mut self) -> Result<Vec<&'a Value>, JsonPathError> {
454        self._select()?;
455
456        match &self.current {
457            Some(r) => Ok(r.to_vec()),
458            _ => Err(JsonPathError::EmptyValue),
459        }
460    }
461
462    fn compute_absolute_path_filter(&mut self, token: &ParseToken) -> bool {
463        if !self.selectors.is_empty() {
464            match token {
465                ParseToken::Absolute | ParseToken::Relative | ParseToken::Filter(_) => {
466                    let selector = self.selectors.pop().unwrap();
467
468                    if let Some(current) = &selector.current {
469                        let term = current.into();
470
471                        if let Some(s) = self.selectors.last_mut() {
472                            s.selector_filter.push_term(Some(term));
473                        } else {
474                            self.selector_filter.push_term(Some(term));
475                        }
476                    } else {
477                        unreachable!()
478                    }
479                }
480                _ => {}
481            }
482        }
483
484        if let Some(selector) = self.selectors.last_mut() {
485            selector.visit_token(token);
486            true
487        } else {
488            false
489        }
490    }
491}
492
493#[allow(deprecated)]
494impl Selector<'_, '_> {
495    fn visit_absolute(&mut self) {
496        if self.current.is_some() {
497            let mut selector = Selector::default();
498
499            if let Some(value) = self.value {
500                selector.value = Some(value);
501                selector.current = Some(vec![value]);
502                self.selectors.push(selector);
503            }
504            return;
505        }
506
507        if let Some(v) = &self.value {
508            self.current = Some(vec![v]);
509        }
510    }
511
512    fn visit_relative(&mut self) {
513        if let Some(ParseToken::Array) = self.tokens.last() {
514            let array_token = self.tokens.pop();
515            if let Some(ParseToken::Leaves) = self.tokens.last() {
516                self.tokens.pop();
517                self.current = self.selector_filter.collect_all(&self.current);
518            }
519            self.tokens.push(array_token.unwrap());
520        }
521        self.selector_filter.new_filter_context();
522    }
523
524    fn visit_array_eof(&mut self) {
525        if self.is_last_before_token_match(ParseToken::Array) {
526            if let Some(Some(e)) = self.selector_filter.pop_term() {
527                if let ExprTerm::String(key) = e {
528                    self.selector_filter
529                        .filter_next_with_str(&self.current, &key);
530                    self.tokens.pop();
531                    return;
532                }
533
534                self.selector_filter.push_term(Some(e));
535            }
536        }
537
538        if self.is_last_before_token_match(ParseToken::Leaves) {
539            self.tokens.pop();
540            self.tokens.pop();
541            if let Some(Some(e)) = self.selector_filter.pop_term() {
542                let selector_filter_consumed = match &e {
543                    ExprTerm::Number(n) => {
544                        self.current = self
545                            .selector_filter
546                            .collect_all_with_num(&self.current, to_f64(n));
547                        self.selector_filter.pop_term();
548                        true
549                    }
550                    ExprTerm::String(key) => {
551                        self.current = self
552                            .selector_filter
553                            .collect_all_with_str(&self.current, key);
554                        self.selector_filter.pop_term();
555                        true
556                    }
557                    _ => {
558                        self.selector_filter.push_term(Some(e));
559                        false
560                    }
561                };
562
563                if selector_filter_consumed {
564                    return;
565                }
566            }
567        }
568
569        if let Some(Some(e)) = self.selector_filter.pop_term() {
570            match e {
571                ExprTerm::Number(n) => {
572                    self.current = self
573                        .selector_filter
574                        .collect_next_with_num(&self.current, to_f64(&n));
575                }
576                ExprTerm::String(key) => {
577                    self.current = self
578                        .selector_filter
579                        .collect_next_with_str(&self.current, &[key]);
580                }
581                ExprTerm::Json(rel, _, v) => {
582                    if v.is_empty() {
583                        self.current = Some(vec![]);
584                    } else if let Some(vec) = rel {
585                        self.current = Some(vec);
586                    } else {
587                        self.current = Some(v);
588                    }
589                }
590                ExprTerm::Bool(false) => {
591                    self.current = Some(vec![]);
592                }
593                _ => {}
594            }
595        }
596
597        self.tokens.pop();
598    }
599
600    fn is_last_before_token_match(&mut self, token: ParseToken) -> bool {
601        if self.tokens.len() > 1 {
602            return token == self.tokens[self.tokens.len() - 2];
603        }
604
605        false
606    }
607
608    fn visit_all(&mut self) {
609        if let Some(ParseToken::Array) = self.tokens.last() {
610            self.tokens.pop();
611        }
612
613        match self.tokens.last() {
614            Some(ParseToken::Leaves) => {
615                self.tokens.pop();
616                self.current = self.selector_filter.collect_all(&self.current);
617            }
618            Some(ParseToken::In) => {
619                self.tokens.pop();
620                self.current = self.selector_filter.collect_next_all(&self.current);
621            }
622            _ => {
623                self.current = self.selector_filter.collect_next_all(&self.current);
624            }
625        }
626    }
627
628    fn visit_key(&mut self, key: &str) {
629        if let Some(ParseToken::Array) = self.tokens.last() {
630            self.selector_filter
631                .push_term(Some(ExprTerm::String(key.to_string())));
632            return;
633        }
634
635        if let Some(t) = self.tokens.pop() {
636            if self.selector_filter.is_term_empty() {
637                match t {
638                    ParseToken::Leaves => {
639                        self.current = self
640                            .selector_filter
641                            .collect_all_with_str(&self.current, key)
642                    }
643                    ParseToken::In => {
644                        self.current = self
645                            .selector_filter
646                            .collect_next_with_str(&self.current, &[key.to_string()])
647                    }
648                    _ => {}
649                }
650            } else {
651                match t {
652                    ParseToken::Leaves => {
653                        self.selector_filter.filter_all_with_str(&self.current, key);
654                    }
655                    ParseToken::In => {
656                        self.selector_filter
657                            .filter_next_with_str(&self.current, key);
658                    }
659                    _ => {}
660                }
661            }
662        }
663    }
664
665    fn visit_keys(&mut self, keys: &[String]) {
666        if !self.selector_filter.is_term_empty() {
667            unimplemented!("keys in filter");
668        }
669
670        if let Some(ParseToken::Array) = self.tokens.pop() {
671            self.current = self
672                .selector_filter
673                .collect_next_with_str(&self.current, keys);
674        } else {
675            unreachable!();
676        }
677    }
678
679    fn visit_filter(&mut self, ft: &FilterToken) {
680        let right = match self.selector_filter.pop_term() {
681            Some(Some(right)) => right,
682            Some(None) => ExprTerm::Json(
683                None,
684                None,
685                match &self.current {
686                    Some(current) => current.to_vec(),
687                    _ => unreachable!(),
688                },
689            ),
690            _ => ExprTerm::Json(None, None, vec![]),
691        };
692
693        let left = match self.selector_filter.pop_term() {
694            Some(Some(left)) => left,
695            Some(None) => ExprTerm::Json(
696                None,
697                None,
698                match &self.current {
699                    Some(current) => current.to_vec(),
700                    _ => unreachable!(),
701                },
702            ),
703            _ => ExprTerm::Json(None, None, vec![]),
704        };
705
706        let mut ret = None;
707        match ft {
708            FilterToken::Equal => left.eq(&right, &mut ret),
709            FilterToken::NotEqual => left.ne(&right, &mut ret),
710            FilterToken::Greater => left.gt(&right, &mut ret),
711            FilterToken::GreaterOrEqual => left.ge(&right, &mut ret),
712            FilterToken::Little => left.lt(&right, &mut ret),
713            FilterToken::LittleOrEqual => left.le(&right, &mut ret),
714            FilterToken::And => left.and(&right, &mut ret),
715            FilterToken::Or => left.or(&right, &mut ret),
716        };
717
718        if let Some(e) = ret {
719            self.selector_filter.push_term(Some(e));
720        }
721    }
722
723    fn visit_range(&mut self, from: &Option<isize>, to: &Option<isize>, step: &Option<usize>) {
724        if !self.selector_filter.is_term_empty() {
725            unimplemented!("range syntax in filter");
726        }
727
728        if let Some(ParseToken::Array) = self.tokens.pop() {
729            let mut tmp = Vec::new();
730            if let Some(current) = &self.current {
731                for v in current {
732                    if let Value::Array(vec) = v {
733                        let from = if let Some(from) = from {
734                            abs_index(*from, vec.len())
735                        } else {
736                            0
737                        };
738
739                        let to = if let Some(to) = to {
740                            abs_index(*to, vec.len())
741                        } else {
742                            vec.len()
743                        };
744
745                        for i in (from..to).step_by(match step {
746                            Some(step) => *step,
747                            _ => 1,
748                        }) {
749                            if let Some(v) = vec.get(i) {
750                                tmp.push(v);
751                            }
752                        }
753                    }
754                }
755            }
756            self.current = Some(tmp);
757        } else {
758            unreachable!();
759        }
760    }
761
762    fn visit_union(&mut self, indices: &[isize]) {
763        if !self.selector_filter.is_term_empty() {
764            unimplemented!("union syntax in filter");
765        }
766
767        if let Some(ParseToken::Array) = self.tokens.pop() {
768            let mut tmp = Vec::new();
769            if let Some(current) = &self.current {
770                for v in current {
771                    if let Value::Array(vec) = v {
772                        for i in indices {
773                            if let Some(v) = vec.get(abs_index(*i, vec.len())) {
774                                tmp.push(v);
775                            }
776                        }
777                    }
778                }
779            }
780
781            self.current = Some(tmp);
782        } else {
783            unreachable!();
784        }
785    }
786}
787
788#[allow(deprecated)]
789impl NodeVisitor for Selector<'_, '_> {
790    fn visit_token(&mut self, token: &ParseToken) {
791        debug!("token: {:?}, stack: {:?}", token, self.tokens);
792
793        if self.compute_absolute_path_filter(token) {
794            return;
795        }
796
797        match token {
798            ParseToken::Absolute => self.visit_absolute(),
799            ParseToken::Relative => self.visit_relative(),
800            ParseToken::In | ParseToken::Leaves | ParseToken::Array => {
801                self.tokens.push(token.clone());
802            }
803            ParseToken::ArrayEof => self.visit_array_eof(),
804            ParseToken::All => self.visit_all(),
805            ParseToken::Bool(b) => {
806                self.selector_filter.push_term(Some(ExprTerm::Bool(*b)));
807            }
808            ParseToken::Key(key) => self.visit_key(key),
809            ParseToken::Keys(keys) => self.visit_keys(keys),
810            ParseToken::Number(v) => {
811                self.selector_filter
812                    .push_term(Some(ExprTerm::Number(Number::from_f64(*v).unwrap())));
813            }
814            ParseToken::Filter(ref ft) => self.visit_filter(ft),
815            ParseToken::Range(from, to, step) => self.visit_range(from, to, step),
816            ParseToken::Union(indices) => self.visit_union(indices),
817            ParseToken::Eof => {
818                debug!("visit_token eof");
819            }
820        }
821    }
822}
823
824#[deprecated(since = "0.4.0", note = "Please use `JsonSelectorMut`")]
825#[derive(Default)]
826pub struct SelectorMut {
827    #[allow(deprecated)]
828    path: Option<Node>,
829    value: Option<Value>,
830}
831
832fn replace_value<F: FnMut(Value) -> Option<Value>>(
833    mut tokens: Vec<String>,
834    value: &mut Value,
835    fun: &mut F,
836) {
837    let mut target = value;
838
839    let last_index = tokens.len().saturating_sub(1);
840    for (i, token) in tokens.drain(..).enumerate() {
841        let target_once = target;
842        let is_last = i == last_index;
843        let target_opt = match *target_once {
844            Value::Object(ref mut map) => {
845                if is_last {
846                    if let Entry::Occupied(mut e) = map.entry(token) {
847                        let v = e.insert(Value::Null);
848                        if let Some(res) = fun(v) {
849                            e.insert(res);
850                        } else {
851                            e.remove();
852                        }
853                    }
854                    return;
855                }
856                map.get_mut(&token)
857            }
858            Value::Array(ref mut vec) => {
859                if let Ok(x) = token.parse::<usize>() {
860                    if is_last {
861                        if x < vec.len() {
862                            let v = std::mem::replace(&mut vec[x], Value::Null);
863                            if let Some(res) = fun(v) {
864                                vec[x] = res;
865                            } else {
866                                vec.remove(x);
867                            }
868                        }
869                        return;
870                    }
871                    vec.get_mut(x)
872                } else {
873                    None
874                }
875            }
876            _ => None,
877        };
878
879        if let Some(t) = target_opt {
880            target = t;
881        } else {
882            break;
883        }
884    }
885}
886
887#[allow(deprecated)]
888impl SelectorMut {
889    pub fn new() -> Self {
890        Self::default()
891    }
892
893    pub fn str_path(&mut self, path: &str) -> Result<&mut Self, JsonPathError> {
894        self.path = Some(Parser::compile(path).map_err(JsonPathError::Path)?);
895        Ok(self)
896    }
897
898    pub fn value(&mut self, value: Value) -> &mut Self {
899        self.value = Some(value);
900        self
901    }
902
903    pub fn take(&mut self) -> Option<Value> {
904        self.value.take()
905    }
906
907    fn compute_paths(&self, mut result: Vec<&Value>) -> Vec<Vec<String>> {
908        fn _walk(
909            origin: &Value,
910            target: &mut Vec<&Value>,
911            tokens: &mut Vec<String>,
912            visited: &mut HashSet<*const Value>,
913            visited_order: &mut Vec<Vec<String>>,
914        ) -> bool {
915            trace!("{:?}, {:?}", target, tokens);
916
917            if target.is_empty() {
918                return true;
919            }
920
921            target.retain(|t| {
922                if std::ptr::eq(origin, *t) {
923                    if visited.insert(*t) {
924                        visited_order.push(tokens.to_vec());
925                    }
926                    false
927                } else {
928                    true
929                }
930            });
931
932            match origin {
933                Value::Array(vec) => {
934                    for (i, v) in vec.iter().enumerate() {
935                        tokens.push(i.to_string());
936                        if _walk(v, target, tokens, visited, visited_order) {
937                            return true;
938                        }
939                        tokens.pop();
940                    }
941                }
942                Value::Object(map) => {
943                    for (k, v) in map {
944                        tokens.push(k.clone());
945                        if _walk(v, target, tokens, visited, visited_order) {
946                            return true;
947                        }
948                        tokens.pop();
949                    }
950                }
951                _ => {}
952            }
953
954            false
955        }
956
957        let mut visited = HashSet::new();
958        let mut visited_order = Vec::new();
959
960        if let Some(origin) = &self.value {
961            let mut tokens = Vec::new();
962            _walk(
963                origin,
964                &mut result,
965                &mut tokens,
966                &mut visited,
967                &mut visited_order,
968            );
969        }
970
971        visited_order
972    }
973
974    pub fn delete(&mut self) -> Result<&mut Self, JsonPathError> {
975        self.replace_with(&mut |_| Some(Value::Null))
976    }
977
978    pub fn remove(&mut self) -> Result<&mut Self, JsonPathError> {
979        self.replace_with(&mut |_| None)
980    }
981
982    fn select(&self) -> Result<Vec<&Value>, JsonPathError> {
983        if let Some(node) = &self.path {
984            let mut selector = Selector::default();
985            selector.compiled_path(node);
986
987            if let Some(value) = &self.value {
988                selector.value(value);
989            }
990
991            Ok(selector.select()?)
992        } else {
993            Err(JsonPathError::EmptyPath)
994        }
995    }
996
997    pub fn replace_with<F: FnMut(Value) -> Option<Value>>(
998        &mut self,
999        fun: &mut F,
1000    ) -> Result<&mut Self, JsonPathError> {
1001        let paths = {
1002            let result = self.select()?;
1003            self.compute_paths(result)
1004        };
1005
1006        if let Some(ref mut value) = &mut self.value {
1007            for tokens in paths {
1008                replace_value(tokens, value, fun);
1009            }
1010        }
1011
1012        Ok(self)
1013    }
1014}
1015
1016// #[cfg(test)]
1017// mod select_inner_tests {
1018//     use serde_json::Value;
1019//
1020//     #[test]
1021//     fn to_f64_i64() {
1022//         let number = 0_i64;
1023//         let v: Value = serde_json::from_str(&format!("{}", number)).unwrap();
1024//         if let Value::Number(n) = v {
1025//             assert!((super::to_f64(&n) - number as f64).abs() == 0_f64);
1026//         } else {
1027//             panic!();
1028//         }
1029//     }
1030//
1031//     #[test]
1032//     fn to_f64_f64() {
1033//         let number = 0.1_f64;
1034//         let v: Value = serde_json::from_str(&format!("{}", number)).unwrap();
1035//         if let Value::Number(n) = v {
1036//             assert!((super::to_f64(&n) - number).abs() == 0_f64);
1037//         } else {
1038//             panic!();
1039//         }
1040//     }
1041//
1042//     #[test]
1043//     fn to_f64_u64() {
1044//         let number = u64::max_value();
1045//         let v: Value = serde_json::from_str(&format!("{}", number)).unwrap();
1046//         if let Value::Number(n) = v {
1047//             assert!((super::to_f64(&n) - number as f64).abs() == 0_f64);
1048//         } else {
1049//             panic!();
1050//         }
1051//     }
1052// }