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