jsonpath_lib/select/
mod.rs

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