1use std::collections::HashSet;
2use std::rc::Rc;
3
4use serde_json::map::Entry;
5use serde_json::{Number, Value};
6
7use super::terms::*;
8use super::utils;
9use crate::paths::{tokens::*, ParserTokenHandler, PathParser, StrRange};
10use crate::JsonPathError;
11use crate::{debug, trace};
12
13#[derive(Debug, Default)]
14pub struct JsonSelector<'a> {
15 parser: Option<Rc<PathParser<'a>>>,
16 value: Option<&'a Value>,
17 tokens: Vec<ParseToken>,
18 current: Option<Vec<&'a Value>>,
19 selectors: Vec<JsonSelector<'a>>,
20 selector_filter: FilterTerms<'a>,
21}
22
23impl<'a> JsonSelector<'a> {
24 pub fn new(parser: PathParser<'a>) -> Self {
25 JsonSelector {
26 parser: Some(Rc::new(parser)),
27 value: None,
28 tokens: Vec::new(),
29 current: None,
30 selectors: Vec::new(),
31 selector_filter: FilterTerms(Vec::new()),
32 }
33 }
34
35 pub fn new_ref(parser: Rc<PathParser<'a>>) -> Self {
36 JsonSelector {
37 parser: Some(parser),
38 value: None,
39 tokens: Vec::new(),
40 current: None,
41 selectors: Vec::new(),
42 selector_filter: FilterTerms(Vec::new()),
43 }
44 }
45
46 pub fn reset_parser(&mut self, parser: PathParser<'a>) -> &mut Self {
47 self.parser = Some(Rc::new(parser));
48 self
49 }
50
51 pub fn reset_parser_ref(&mut self, parser: Rc<PathParser<'a>>) -> &mut Self {
52 self.parser = Some(parser);
53 self
54 }
55
56 pub fn reset_value(&mut self) -> &mut Self {
57 self.current = None;
58 self
59 }
60
61 pub fn value(&mut self, v: &'a Value) -> &mut Self {
62 self.value = Some(v);
63 self
64 }
65
66 fn _select(&mut self) -> Result<(), JsonPathError> {
67 let parser = self.parser.take();
68 if let Some(parser) = parser.as_ref() {
69 let _ = parser.parse(self);
70 }
71 self.parser = parser;
72
73 Ok(())
74 }
75
76 pub fn select_as<T: serde::de::DeserializeOwned>(&mut self) -> Result<Vec<T>, JsonPathError> {
77 self._select()?;
78
79 match &self.current {
80 Some(vec) => {
81 let mut ret = Vec::new();
82 for v in vec {
83 match T::deserialize(*v) {
84 Ok(v) => ret.push(v),
85 Err(e) => return Err(JsonPathError::Serde(e.to_string())),
86 }
87 }
88 Ok(ret)
89 }
90 _ => Err(JsonPathError::EmptyValue),
91 }
92 }
93
94 pub fn select_as_str(&mut self) -> Result<String, JsonPathError> {
95 self._select()?;
96
97 match &self.current {
98 Some(r) => {
99 Ok(serde_json::to_string(r).map_err(|e| JsonPathError::Serde(e.to_string()))?)
100 }
101 _ => Err(JsonPathError::EmptyValue),
102 }
103 }
104
105 pub fn select(&mut self) -> Result<Vec<&'a Value>, JsonPathError> {
106 self._select()?;
107
108 match &self.current {
109 Some(r) => Ok(r.to_vec()),
110 _ => Err(JsonPathError::EmptyValue),
111 }
112 }
113
114 fn compute_absolute_path_filter<F>(
115 &mut self,
116 token: &ParseToken,
117 parse_value_reader: &F,
118 ) -> bool
119 where
120 F: Fn(&StrRange) -> &'a str,
121 {
122 if !self.selectors.is_empty() {
123 match token {
124 ParseToken::Absolute | ParseToken::Relative | ParseToken::Filter(_) => {
125 let selector = self.selectors.pop().unwrap();
126
127 if let Some(current) = &selector.current {
128 let term = current.into();
129
130 if let Some(s) = self.selectors.last_mut() {
131 s.selector_filter.push_term(Some(term));
132 } else {
133 self.selector_filter.push_term(Some(term));
134 }
135 } else {
136 unreachable!()
137 }
138 }
139 _ => {}
140 }
141 }
142
143 if self.selectors.is_empty() {
144 return false;
145 }
146
147 self.selectors
148 .last_mut()
149 .unwrap()
150 .handle(token, parse_value_reader);
151 true
152 }
153}
154
155impl<'a> JsonSelector<'a> {
156 fn visit_absolute(&mut self) {
157 if self.current.is_some() {
158 if let Some(value) = self.value {
159 let selector = JsonSelector {
160 parser: None,
161 value: Some(value),
162 tokens: Vec::new(),
163 current: Some(vec![value]),
164 selectors: Vec::new(),
165 selector_filter: FilterTerms(Vec::new()),
166 };
167 self.selectors.push(selector);
168 }
169 return;
170 }
171
172 if let Some(v) = &self.value {
173 self.current = Some(vec![v]);
174 }
175 }
176
177 fn visit_relative(&mut self) {
178 if let Some(ParseToken::Array) = self.tokens.last() {
179 let array_token = self.tokens.pop();
180 if let Some(ParseToken::Leaves) = self.tokens.last() {
181 self.tokens.pop();
182 self.current = self.selector_filter.collect_all(self.current.take());
183 }
184 self.tokens.push(array_token.unwrap());
185 }
186 self.selector_filter.new_filter_context();
187 }
188
189 fn visit_array_eof(&mut self) {
190 if self.is_last_before_token_match(ParseToken::Array) {
191 if let Some(Some(e)) = self.selector_filter.pop_term() {
192 if let ExprTerm::String(key) = e {
193 self.current = self
194 .selector_filter
195 .filter_next_with_str(self.current.take(), key);
196 self.tokens.pop();
197 return;
198 }
199
200 self.selector_filter.push_term(Some(e));
201 }
202 }
203
204 if self.is_last_before_token_match(ParseToken::Leaves) {
205 self.tokens.pop();
206 self.tokens.pop();
207 if let Some(Some(e)) = self.selector_filter.pop_term() {
208 let selector_filter_consumed = match e {
209 ExprTerm::Number(n) => {
210 self.current = self
211 .selector_filter
212 .collect_all_with_num(self.current.take(), utils::to_f64(&n));
213 self.selector_filter.pop_term();
214 true
215 }
216 ExprTerm::String(key) => {
217 self.current = self
218 .selector_filter
219 .collect_all_with_str(self.current.take(), key);
220 self.selector_filter.pop_term();
221 true
222 }
223 _ => {
224 self.selector_filter.push_term(Some(e));
225 false
226 }
227 };
228
229 if selector_filter_consumed {
230 return;
231 }
232 }
233 }
234
235 if let Some(Some(e)) = self.selector_filter.pop_term() {
236 match e {
237 ExprTerm::Number(n) => {
238 self.current = self
239 .selector_filter
240 .collect_next_with_num(self.current.take(), utils::to_f64(&n));
241 }
242 ExprTerm::String(key) => {
243 self.current = self
244 .selector_filter
245 .collect_next_with_str(self.current.take(), &[key]);
246 }
247 ExprTerm::Json(rel, _, v) => {
248 if v.is_empty() {
249 self.current = Some(Vec::new());
250 } else if let Some(vec) = rel {
251 self.current = Some(vec);
252 } else {
253 self.current = Some(v);
254 }
255 }
256 ExprTerm::Bool(false) => {
257 self.current = Some(vec![]);
258 }
259 _ => {}
260 }
261 }
262
263 self.tokens.pop();
264 }
265
266 fn is_last_before_token_match(&mut self, token: ParseToken) -> bool {
267 if self.tokens.len() > 1 {
268 return token == self.tokens[self.tokens.len() - 2];
269 }
270
271 false
272 }
273
274 fn visit_all(&mut self) {
275 if let Some(ParseToken::Array) = self.tokens.last() {
276 self.tokens.pop();
277 }
278
279 match self.tokens.last() {
280 Some(ParseToken::Leaves) => {
281 self.tokens.pop();
282 self.current = self.selector_filter.collect_all(self.current.take());
283 }
284 Some(ParseToken::In) => {
285 self.tokens.pop();
286 self.current = self.selector_filter.collect_next_all(self.current.take());
287 }
288 _ => {
289 self.current = self.selector_filter.collect_next_all(self.current.take());
290 }
291 }
292 }
293
294 fn visit_key(&mut self, key: &'a str) {
295 if let Some(ParseToken::Array) = self.tokens.last() {
296 self.selector_filter.push_term(Some(ExprTerm::String(key)));
297 return;
298 }
299
300 if let Some(t) = self.tokens.pop() {
301 if self.selector_filter.is_term_empty() {
302 match t {
303 ParseToken::Leaves => {
304 self.current = self
305 .selector_filter
306 .collect_all_with_str(self.current.take(), key)
307 }
308 ParseToken::In => {
309 self.current = self
310 .selector_filter
311 .collect_next_with_str(self.current.take(), &[key])
312 }
313 _ => {}
314 }
315 } else {
316 match t {
317 ParseToken::Leaves => {
318 self.current = self
319 .selector_filter
320 .filter_all_with_str(self.current.take(), key);
321 }
322 ParseToken::In => {
323 self.current = self
324 .selector_filter
325 .filter_next_with_str(self.current.take(), key);
326 }
327 _ => {}
328 }
329 }
330 }
331 }
332
333 fn visit_keys(&mut self, keys: &[&'a str]) {
334 if !self.selector_filter.is_term_empty() {
335 unimplemented!("keys in filter");
336 }
337
338 if let Some(ParseToken::Array) = self.tokens.pop() {
339 self.current = self
340 .selector_filter
341 .collect_next_with_str(self.current.take(), keys);
342 } else {
343 unreachable!();
344 }
345 }
346
347 fn visit_filter(&mut self, ft: &FilterToken) {
348 let right = match self.selector_filter.pop_term() {
349 Some(Some(right)) => right,
350 Some(None) => ExprTerm::Json(
351 None,
352 None,
353 match &self.current {
354 Some(current) => current.to_vec(),
355 _ => unreachable!(),
356 },
357 ),
358 _ => ExprTerm::Json(None, None, vec![]), };
360
361 let mut left = match self.selector_filter.pop_term() {
362 Some(Some(left)) => left,
363 Some(None) => ExprTerm::Json(
364 None,
365 None,
366 match &self.current {
367 Some(current) => current.to_vec(),
368 _ => unreachable!(),
369 },
370 ),
371 _ => ExprTerm::Json(None, None, vec![]), };
373
374 let expr = match ft {
375 FilterToken::Equal => left.eq_(right),
376 FilterToken::NotEqual => left.ne_(right),
377 FilterToken::Greater => left.gt(right),
378 FilterToken::GreaterOrEqual => left.ge(right),
379 FilterToken::Little => left.lt(right),
380 FilterToken::LittleOrEqual => left.le(right),
381 FilterToken::And => left.and(right),
382 FilterToken::Or => left.or(right),
383 };
384
385 self.selector_filter.push_term(Some(expr));
386 }
387
388 fn visit_range(&mut self, from: &Option<isize>, to: &Option<isize>, step: &Option<usize>) {
389 if !self.selector_filter.is_term_empty() {
390 unimplemented!("range syntax in filter");
391 }
392
393 if let Some(ParseToken::Array) = self.tokens.pop() {
394 let mut tmp = Vec::new();
395 if let Some(current) = &self.current {
396 for v in current {
397 if let Value::Array(vec) = v {
398 let from = if let Some(from) = from {
399 utils::abs_index(*from, vec.len())
400 } else {
401 0
402 };
403
404 let to = if let Some(to) = to {
405 utils::abs_index(*to, vec.len())
406 } else {
407 vec.len()
408 };
409
410 for i in (from..to).step_by(match step {
411 Some(step) => *step,
412 _ => 1,
413 }) {
414 if let Some(v) = vec.get(i) {
415 tmp.push(v);
416 }
417 }
418 }
419 }
420 }
421 self.current = Some(tmp);
422 } else {
423 unreachable!();
424 }
425 }
426
427 fn visit_union(&mut self, indices: &[isize]) {
428 if !self.selector_filter.is_term_empty() {
429 unimplemented!("union syntax in filter");
430 }
431
432 if let Some(ParseToken::Array) = self.tokens.pop() {
433 let mut tmp = Vec::new();
434 if let Some(current) = &self.current {
435 for v in current {
436 if let Value::Array(vec) = v {
437 for i in indices {
438 if let Some(v) = vec.get(utils::abs_index(*i, vec.len())) {
439 tmp.push(v);
440 }
441 }
442 }
443 }
444 }
445
446 self.current = Some(tmp);
447 } else {
448 unreachable!();
449 }
450 }
451}
452
453impl<'a> ParserTokenHandler<'a> for JsonSelector<'a> {
454 fn handle<F>(&mut self, token: &ParseToken, parse_value_reader: &F)
455 where
456 F: Fn(&StrRange) -> &'a str,
457 {
458 debug!("token: {:?}, stack: {:?}", token, self.tokens);
459
460 if self.compute_absolute_path_filter(token, parse_value_reader) {
461 return;
462 }
463
464 match token {
465 ParseToken::Absolute => self.visit_absolute(),
466 ParseToken::Relative => self.visit_relative(),
467 ParseToken::In | ParseToken::Leaves | ParseToken::Array => {
468 self.tokens.push(token.clone());
469 }
470 ParseToken::ArrayEof => self.visit_array_eof(),
471 ParseToken::All => self.visit_all(),
472 ParseToken::Bool(b) => {
473 self.selector_filter.push_term(Some(ExprTerm::Bool(*b)));
474 }
475 ParseToken::Key(s) => {
476 let key = parse_value_reader(s);
477 self.visit_key(key);
478 }
479 ParseToken::Keys(keys) => {
480 let keys: Vec<&str> = keys.iter().map(parse_value_reader).collect();
481 self.visit_keys(&keys)
482 }
483 ParseToken::Number(v) => {
484 self.selector_filter
485 .push_term(Some(ExprTerm::Number(Number::from_f64(*v).unwrap())));
486 }
487 ParseToken::Filter(ref ft) => self.visit_filter(ft),
488 ParseToken::Range(from, to, step) => self.visit_range(from, to, step),
489 ParseToken::Union(indices) => self.visit_union(indices),
490 ParseToken::Eof => {
491 debug!("visit_token eof");
492 }
493 }
494 }
495}
496
497#[derive(Default)]
498pub struct JsonSelectorMut<'a> {
499 value: Option<Value>,
500 parser: Option<Rc<PathParser<'a>>>,
501}
502
503impl<'a> JsonSelectorMut<'a> {
504 pub fn new(parser: PathParser<'a>) -> Self {
505 Self::new_ref(Rc::new(parser))
506 }
507
508 pub fn new_ref(parser: Rc<PathParser<'a>>) -> Self {
509 JsonSelectorMut {
510 value: None,
511 parser: Some(parser),
512 }
513 }
514
515 pub fn reset_parser(&mut self, parser: PathParser<'a>) -> &mut Self {
516 self.parser = Some(Rc::new(parser));
517 self
518 }
519
520 pub fn reset_parser_ref(&mut self, parser: Rc<PathParser<'a>>) -> &mut Self {
521 self.parser = Some(parser);
522 self
523 }
524
525 pub fn value(&mut self, value: Value) -> &mut Self {
526 self.value = Some(value);
527 self
528 }
529
530 pub fn take(&mut self) -> Option<Value> {
531 self.value.take()
532 }
533
534 pub fn delete(&mut self) -> Result<&mut Self, JsonPathError> {
535 self.replace_with(&mut |_| Some(Value::Null))
536 }
537
538 pub fn remove(&mut self) -> Result<&mut Self, JsonPathError> {
539 self.replace_with(&mut |_| None)
540 }
541
542 fn select(&self) -> Result<Vec<&Value>, JsonPathError> {
543 let mut selector = JsonSelector::default();
544
545 if let Some(parser) = self.parser.as_ref() {
546 selector.reset_parser_ref(Rc::clone(parser));
547 } else {
548 return Err(JsonPathError::EmptyPath);
549 }
550
551 if let Some(value) = self.value.as_ref() {
552 selector.value(value);
553 } else {
554 return Err(JsonPathError::EmptyValue);
555 }
556
557 selector.select()
558 }
559
560 pub fn replace_with<F>(&mut self, fun: &mut F) -> Result<&mut Self, JsonPathError>
561 where
562 F: FnMut(Value) -> Option<Value>,
563 {
564 let result = self.select()?;
565 let paths = self.compute_paths(result);
566
567 if let Some(ref mut value) = &mut self.value {
568 for tokens in paths {
569 Self::replace_value(tokens, value, fun);
570 }
571 }
572
573 Ok(self)
574 }
575
576 fn replace_value<F>(mut tokens: Vec<String>, value: &mut Value, fun: &mut F)
577 where
578 F: FnMut(Value) -> Option<Value>,
579 {
580 let mut target = value;
581
582 let last_index = tokens.len().saturating_sub(1);
583 for (i, token) in tokens.drain(..).enumerate() {
584 let target_once = target;
585 let is_last = i == last_index;
586 let target_opt = match *target_once {
587 Value::Object(ref mut map) => {
588 if is_last {
589 if let Entry::Occupied(mut e) = map.entry(token) {
590 let v = e.insert(Value::Null);
591 if let Some(res) = fun(v) {
592 e.insert(res);
593 } else {
594 e.remove();
595 }
596 }
597 return;
598 }
599 map.get_mut(&token)
600 }
601 Value::Array(ref mut vec) => {
602 if let Ok(x) = token.parse::<usize>() {
603 if is_last {
604 if x < vec.len() {
605 let v = std::mem::replace(&mut vec[x], Value::Null);
606 if let Some(res) = fun(v) {
607 vec[x] = res;
608 } else {
609 vec.remove(x);
610 }
611 }
612 return;
613 }
614 vec.get_mut(x)
615 } else {
616 None
617 }
618 }
619 _ => None,
620 };
621
622 if let Some(t) = target_opt {
623 target = t;
624 } else {
625 break;
626 }
627 }
628 }
629
630 fn compute_paths(&self, mut result: Vec<&Value>) -> Vec<Vec<String>> {
631 let mut visited = HashSet::new();
632 let mut visited_order = Vec::new();
633
634 if let Some(origin) = &self.value {
635 let mut tokens = Vec::new();
636 Self::walk(
637 origin,
638 &mut result,
639 &mut tokens,
640 &mut visited,
641 &mut visited_order,
642 );
643 }
644
645 visited_order
646 }
647
648 fn walk(
649 origin: &Value,
650 target: &mut Vec<&Value>,
651 tokens: &mut Vec<String>,
652 visited: &mut HashSet<*const Value>,
653 visited_order: &mut Vec<Vec<String>>,
654 ) -> bool {
655 trace!("{:?}, {:?}", target, tokens);
656
657 if target.is_empty() {
658 return true;
659 }
660
661 target.retain(|t| {
662 if std::ptr::eq(origin, *t) {
663 if visited.insert(*t) {
664 visited_order.push(tokens.to_vec());
665 }
666 false
667 } else {
668 true
669 }
670 });
671
672 match origin {
673 Value::Array(vec) => {
674 for (i, v) in vec.iter().enumerate() {
675 tokens.push(i.to_string());
676 if Self::walk(v, target, tokens, visited, visited_order) {
677 return true;
678 }
679 tokens.pop();
680 }
681 }
682 Value::Object(map) => {
683 for (k, v) in map {
684 tokens.push(k.clone());
685 if Self::walk(v, target, tokens, visited, visited_order) {
686 return true;
687 }
688 tokens.pop();
689 }
690 }
691 _ => {}
692 }
693
694 false
695 }
696}