1 | use std::collections::HashSet; |
2 | use std::fmt; |
3 | |
4 | use serde_json::{Number, Value}; |
5 | use serde_json::map::Entry; |
6 | |
7 | use parser::*; |
8 | |
9 | use self::expr_term::*; |
10 | use self::value_walker::ValueWalker; |
11 | |
12 | mod cmp; |
13 | mod expr_term; |
14 | mod value_walker; |
15 | |
16 | fn 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 | |
26 | fn 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)] |
35 | enum FilterKey { |
36 | String(String), |
37 | All, |
38 | } |
39 | |
40 | pub enum JsonPathError { |
41 | EmptyPath, |
42 | EmptyValue, |
43 | Path(String), |
44 | Serde(String), |
45 | } |
46 | |
47 | impl std::error::Error for JsonPathError {} |
48 | |
49 | impl fmt::Debug for JsonPathError { |
50 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
51 | write!(f, " {}" , self) |
52 | } |
53 | } |
54 | |
55 | impl fmt::Display for JsonPathError { |
56 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
57 | match self { |
58 | JsonPathError::EmptyPath => f.write_str(data:"path not set" ), |
59 | JsonPathError::EmptyValue => f.write_str(data:"json value not set" ), |
60 | JsonPathError::Path(msg: &String) => f.write_str(&format!("path error: \n{}\n" , msg)), |
61 | JsonPathError::Serde(msg: &String) => f.write_str(&format!("serde error: \n{}\n" , msg)), |
62 | } |
63 | } |
64 | } |
65 | |
66 | #[derive (Debug, Default)] |
67 | struct FilterTerms<'a>(Vec<Option<ExprTerm<'a>>>); |
68 | |
69 | impl<'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: {:?}" , ¤t); |
131 | |
132 | if let Some(current) = ¤t { |
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, ¤t |
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 : {:?}" , ¤t); |
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, ¤t |
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(¤t, &mut tmp); |
298 | return Some(tmp); |
299 | } |
300 | debug!("collect_all: {:?}" , ¤t); |
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(¤t, &mut tmp, key, false); |
309 | return Some(tmp); |
310 | } |
311 | |
312 | debug!("collect_all_with_str: {}, {:?}" , key, ¤t); |
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(¤t, &mut tmp, index); |
321 | return Some(tmp); |
322 | } |
323 | |
324 | debug!("collect_all_with_num: {}, {:?}" , index, ¤t); |
325 | |
326 | None |
327 | } |
328 | } |
329 | |
330 | #[derive (Debug, Default)] |
331 | pub struct Selector<'a, 'b> { |
332 | node: Option<Node>, |
333 | node_ref: Option<&'b Node>, |
334 | value: Option<&'a Value>, |
335 | tokens: Vec<ParseToken>, |
336 | current: Option<Vec<&'a Value>>, |
337 | selectors: Vec<Selector<'a, 'b>>, |
338 | selector_filter: FilterTerms<'a>, |
339 | } |
340 | |
341 | impl<'a, 'b> Selector<'a, 'b> { |
342 | pub fn new() -> Self { |
343 | Self::default() |
344 | } |
345 | |
346 | pub fn str_path(&mut self, path: &str) -> Result<&mut Self, JsonPathError> { |
347 | debug!("path : {}" , path); |
348 | self.node_ref.take(); |
349 | self.node = Some(Parser::compile(path).map_err(JsonPathError::Path)?); |
350 | Ok(self) |
351 | } |
352 | |
353 | pub fn node_ref(&self) -> Option<&Node> { |
354 | if let Some(node) = &self.node { |
355 | return Some(node); |
356 | } |
357 | |
358 | if let Some(node) = &self.node_ref { |
359 | return Some(*node); |
360 | } |
361 | |
362 | None |
363 | } |
364 | |
365 | pub fn compiled_path(&mut self, node: &'b Node) -> &mut Self { |
366 | self.node.take(); |
367 | self.node_ref = Some(node); |
368 | self |
369 | } |
370 | |
371 | pub fn reset_value(&mut self) -> &mut Self { |
372 | self.current = None; |
373 | self |
374 | } |
375 | |
376 | pub fn value(&mut self, v: &'a Value) -> &mut Self { |
377 | self.value = Some(v); |
378 | self |
379 | } |
380 | |
381 | fn _select(&mut self) -> Result<(), JsonPathError> { |
382 | if self.node_ref.is_some() { |
383 | let node_ref = self.node_ref.take().unwrap(); |
384 | self.visit(node_ref); |
385 | return Ok(()); |
386 | } |
387 | |
388 | if self.node.is_none() { |
389 | return Err(JsonPathError::EmptyPath); |
390 | } |
391 | |
392 | let node = self.node.take().unwrap(); |
393 | self.visit(&node); |
394 | self.node = Some(node); |
395 | |
396 | Ok(()) |
397 | } |
398 | |
399 | pub fn select_as<T: serde::de::DeserializeOwned>(&mut self) -> Result<Vec<T>, JsonPathError> { |
400 | self._select()?; |
401 | |
402 | match &self.current { |
403 | Some(vec) => { |
404 | let mut ret = Vec::new(); |
405 | for v in vec { |
406 | match T::deserialize(*v) { |
407 | Ok(v) => ret.push(v), |
408 | Err(e) => return Err(JsonPathError::Serde(e.to_string())), |
409 | } |
410 | } |
411 | Ok(ret) |
412 | } |
413 | _ => Err(JsonPathError::EmptyValue), |
414 | } |
415 | } |
416 | |
417 | pub fn select_as_str(&mut self) -> Result<String, JsonPathError> { |
418 | self._select()?; |
419 | |
420 | match &self.current { |
421 | Some(r) => { |
422 | Ok(serde_json::to_string(r).map_err(|e| JsonPathError::Serde(e.to_string()))?) |
423 | } |
424 | _ => Err(JsonPathError::EmptyValue), |
425 | } |
426 | } |
427 | |
428 | pub fn select(&mut self) -> Result<Vec<&'a Value>, JsonPathError> { |
429 | self._select()?; |
430 | |
431 | match &self.current { |
432 | Some(r) => Ok(r.to_vec()), |
433 | _ => Err(JsonPathError::EmptyValue), |
434 | } |
435 | } |
436 | |
437 | fn compute_absolute_path_filter(&mut self, token: &ParseToken) -> bool { |
438 | if !self.selectors.is_empty() { |
439 | match token { |
440 | ParseToken::Absolute | ParseToken::Relative | ParseToken::Filter(_) => { |
441 | let selector = self.selectors.pop().unwrap(); |
442 | |
443 | if let Some(current) = &selector.current { |
444 | let term = current.into(); |
445 | |
446 | if let Some(s) = self.selectors.last_mut() { |
447 | s.selector_filter.push_term(Some(term)); |
448 | } else { |
449 | self.selector_filter.push_term(Some(term)); |
450 | } |
451 | } else { |
452 | unreachable!() |
453 | } |
454 | } |
455 | _ => {} |
456 | } |
457 | } |
458 | |
459 | if let Some(selector) = self.selectors.last_mut() { |
460 | selector.visit_token(token); |
461 | true |
462 | } else { |
463 | false |
464 | } |
465 | } |
466 | } |
467 | |
468 | impl<'a, 'b> Selector<'a, 'b> { |
469 | fn visit_absolute(&mut self) { |
470 | if self.current.is_some() { |
471 | let mut selector = Selector::default(); |
472 | |
473 | if let Some(value) = self.value { |
474 | selector.value = Some(value); |
475 | selector.current = Some(vec![value]); |
476 | self.selectors.push(selector); |
477 | } |
478 | return; |
479 | } |
480 | |
481 | if let Some(v) = &self.value { |
482 | self.current = Some(vec![v]); |
483 | } |
484 | } |
485 | |
486 | fn visit_relative(&mut self) { |
487 | if let Some(ParseToken::Array) = self.tokens.last() { |
488 | let array_token = self.tokens.pop(); |
489 | if let Some(ParseToken::Leaves) = self.tokens.last() { |
490 | self.tokens.pop(); |
491 | self.current = self.selector_filter.collect_all(&self.current); |
492 | } |
493 | self.tokens.push(array_token.unwrap()); |
494 | } |
495 | self.selector_filter.new_filter_context(); |
496 | } |
497 | |
498 | fn visit_array_eof(&mut self) { |
499 | if self.is_last_before_token_match(ParseToken::Array) { |
500 | if let Some(Some(e)) = self.selector_filter.pop_term() { |
501 | if let ExprTerm::String(key) = e { |
502 | self.selector_filter.filter_next_with_str(&self.current, &key); |
503 | self.tokens.pop(); |
504 | return; |
505 | } |
506 | |
507 | self.selector_filter.push_term(Some(e)); |
508 | } |
509 | } |
510 | |
511 | if self.is_last_before_token_match(ParseToken::Leaves) { |
512 | self.tokens.pop(); |
513 | self.tokens.pop(); |
514 | if let Some(Some(e)) = self.selector_filter.pop_term() { |
515 | let selector_filter_consumed = match &e { |
516 | ExprTerm::Number(n) => { |
517 | self.current = self.selector_filter.collect_all_with_num(&self.current, to_f64(n)); |
518 | self.selector_filter.pop_term(); |
519 | true |
520 | } |
521 | ExprTerm::String(key) => { |
522 | self.current = self.selector_filter.collect_all_with_str(&self.current, key); |
523 | self.selector_filter.pop_term(); |
524 | true |
525 | } |
526 | _ => { |
527 | self.selector_filter.push_term(Some(e)); |
528 | false |
529 | } |
530 | }; |
531 | |
532 | if selector_filter_consumed { |
533 | return; |
534 | } |
535 | } |
536 | } |
537 | |
538 | if let Some(Some(e)) = self.selector_filter.pop_term() { |
539 | match e { |
540 | ExprTerm::Number(n) => { |
541 | self.current = self.selector_filter.collect_next_with_num(&self.current, to_f64(&n)); |
542 | } |
543 | ExprTerm::String(key) => { |
544 | self.current = self.selector_filter.collect_next_with_str(&self.current, &[key]); |
545 | } |
546 | ExprTerm::Json(rel, _, v) => { |
547 | if v.is_empty() { |
548 | self.current = Some(vec![]); |
549 | } else if let Some(vec) = rel { |
550 | self.current = Some(vec); |
551 | } else { |
552 | self.current = Some(v); |
553 | } |
554 | } |
555 | ExprTerm::Bool(false) => { |
556 | self.current = Some(vec![]); |
557 | } |
558 | _ => {} |
559 | } |
560 | } |
561 | |
562 | self.tokens.pop(); |
563 | } |
564 | |
565 | fn is_last_before_token_match(&mut self, token: ParseToken) -> bool { |
566 | if self.tokens.len() > 1 { |
567 | return token == self.tokens[self.tokens.len() - 2]; |
568 | } |
569 | |
570 | false |
571 | } |
572 | |
573 | fn visit_all(&mut self) { |
574 | if let Some(ParseToken::Array) = self.tokens.last() { |
575 | self.tokens.pop(); |
576 | } |
577 | |
578 | match self.tokens.last() { |
579 | Some(ParseToken::Leaves) => { |
580 | self.tokens.pop(); |
581 | self.current = self.selector_filter.collect_all(&self.current); |
582 | } |
583 | Some(ParseToken::In) => { |
584 | self.tokens.pop(); |
585 | self.current = self.selector_filter.collect_next_all(&self.current); |
586 | } |
587 | _ => { |
588 | self.current = self.selector_filter.collect_next_all(&self.current); |
589 | } |
590 | } |
591 | } |
592 | |
593 | fn visit_key(&mut self, key: &str) { |
594 | if let Some(ParseToken::Array) = self.tokens.last() { |
595 | self.selector_filter.push_term(Some(ExprTerm::String(key.to_string()))); |
596 | return; |
597 | } |
598 | |
599 | if let Some(t) = self.tokens.pop() { |
600 | if self.selector_filter.is_term_empty() { |
601 | match t { |
602 | ParseToken::Leaves => { |
603 | self.current = self.selector_filter.collect_all_with_str(&self.current, key) |
604 | } |
605 | ParseToken::In => { |
606 | self.current = self.selector_filter.collect_next_with_str(&self.current, &[key.to_string()]) |
607 | } |
608 | _ => {} |
609 | } |
610 | } else { |
611 | match t { |
612 | ParseToken::Leaves => { |
613 | self.selector_filter.filter_all_with_str(&self.current, key); |
614 | } |
615 | ParseToken::In => { |
616 | self.selector_filter.filter_next_with_str(&self.current, key); |
617 | } |
618 | _ => {} |
619 | } |
620 | } |
621 | } |
622 | } |
623 | |
624 | fn visit_keys(&mut self, keys: &[String]) { |
625 | if !self.selector_filter.is_term_empty() { |
626 | unimplemented!("keys in filter" ); |
627 | } |
628 | |
629 | if let Some(ParseToken::Array) = self.tokens.pop() { |
630 | self.current = self.selector_filter.collect_next_with_str(&self.current, keys); |
631 | } else { |
632 | unreachable!(); |
633 | } |
634 | } |
635 | |
636 | fn visit_filter(&mut self, ft: &FilterToken) { |
637 | let right = match self.selector_filter.pop_term() { |
638 | Some(Some(right)) => right, |
639 | Some(None) => ExprTerm::Json( |
640 | None, |
641 | None, |
642 | match &self.current { |
643 | Some(current) => current.to_vec(), |
644 | _ => unreachable!(), |
645 | }, |
646 | ), |
647 | _ => panic!("empty term right" ), |
648 | }; |
649 | |
650 | let left = match self.selector_filter.pop_term() { |
651 | Some(Some(left)) => left, |
652 | Some(None) => ExprTerm::Json( |
653 | None, |
654 | None, |
655 | match &self.current { |
656 | Some(current) => current.to_vec(), |
657 | _ => unreachable!(), |
658 | }, |
659 | ), |
660 | _ => panic!("empty term left" ), |
661 | }; |
662 | |
663 | let mut ret = None; |
664 | match ft { |
665 | FilterToken::Equal => left.eq(&right, &mut ret), |
666 | FilterToken::NotEqual => left.ne(&right, &mut ret), |
667 | FilterToken::Greater => left.gt(&right, &mut ret), |
668 | FilterToken::GreaterOrEqual => left.ge(&right, &mut ret), |
669 | FilterToken::Little => left.lt(&right, &mut ret), |
670 | FilterToken::LittleOrEqual => left.le(&right, &mut ret), |
671 | FilterToken::And => left.and(&right, &mut ret), |
672 | FilterToken::Or => left.or(&right, &mut ret), |
673 | }; |
674 | |
675 | if let Some(e) = ret { |
676 | self.selector_filter.push_term(Some(e)); |
677 | } |
678 | } |
679 | |
680 | fn visit_range(&mut self, from: &Option<isize>, to: &Option<isize>, step: &Option<usize>) { |
681 | if !self.selector_filter.is_term_empty() { |
682 | unimplemented!("range syntax in filter" ); |
683 | } |
684 | |
685 | if let Some(ParseToken::Array) = self.tokens.pop() { |
686 | let mut tmp = Vec::new(); |
687 | if let Some(current) = &self.current { |
688 | for v in current { |
689 | if let Value::Array(vec) = v { |
690 | let from = if let Some(from) = from { |
691 | abs_index(*from, vec.len()) |
692 | } else { |
693 | 0 |
694 | }; |
695 | |
696 | let to = if let Some(to) = to { |
697 | abs_index(*to, vec.len()) |
698 | } else { |
699 | vec.len() |
700 | }; |
701 | |
702 | for i in (from..to).step_by(match step { |
703 | Some(step) => *step, |
704 | _ => 1, |
705 | }) { |
706 | if let Some(v) = vec.get(i) { |
707 | tmp.push(v); |
708 | } |
709 | } |
710 | } |
711 | } |
712 | } |
713 | self.current = Some(tmp); |
714 | } else { |
715 | unreachable!(); |
716 | } |
717 | } |
718 | |
719 | fn visit_union(&mut self, indices: &[isize]) { |
720 | if !self.selector_filter.is_term_empty() { |
721 | unimplemented!("union syntax in filter" ); |
722 | } |
723 | |
724 | if let Some(ParseToken::Array) = self.tokens.pop() { |
725 | let mut tmp = Vec::new(); |
726 | if let Some(current) = &self.current { |
727 | for v in current { |
728 | if let Value::Array(vec) = v { |
729 | for i in indices { |
730 | if let Some(v) = vec.get(abs_index(*i, vec.len())) { |
731 | tmp.push(v); |
732 | } |
733 | } |
734 | } |
735 | } |
736 | } |
737 | |
738 | self.current = Some(tmp); |
739 | } else { |
740 | unreachable!(); |
741 | } |
742 | } |
743 | } |
744 | |
745 | impl<'a, 'b> NodeVisitor for Selector<'a, 'b> { |
746 | fn visit_token(&mut self, token: &ParseToken) { |
747 | debug!("token: {:?}, stack: {:?}" , token, self.tokens); |
748 | |
749 | if self.compute_absolute_path_filter(token) { |
750 | return; |
751 | } |
752 | |
753 | match token { |
754 | ParseToken::Absolute => self.visit_absolute(), |
755 | ParseToken::Relative => self.visit_relative(), |
756 | ParseToken::In | ParseToken::Leaves | ParseToken::Array => { |
757 | self.tokens.push(token.clone()); |
758 | } |
759 | ParseToken::ArrayEof => self.visit_array_eof(), |
760 | ParseToken::All => self.visit_all(), |
761 | ParseToken::Bool(b) => { |
762 | self.selector_filter.push_term(Some(ExprTerm::Bool(*b))); |
763 | } |
764 | ParseToken::Key(key) => self.visit_key(key), |
765 | ParseToken::Keys(keys) => self.visit_keys(keys), |
766 | ParseToken::Number(v) => { |
767 | self.selector_filter.push_term(Some(ExprTerm::Number(Number::from_f64(*v).unwrap()))); |
768 | } |
769 | ParseToken::Filter(ref ft) => self.visit_filter(ft), |
770 | ParseToken::Range(from, to, step) => self.visit_range(from, to, step), |
771 | ParseToken::Union(indices) => self.visit_union(indices), |
772 | ParseToken::Eof => { |
773 | debug!("visit_token eof" ); |
774 | } |
775 | } |
776 | } |
777 | } |
778 | |
779 | #[derive (Default)] |
780 | pub struct SelectorMut { |
781 | path: Option<Node>, |
782 | value: Option<Value>, |
783 | } |
784 | |
785 | fn replace_value<F: FnMut(Value) -> Option<Value>>( |
786 | mut tokens: Vec<String>, |
787 | value: &mut Value, |
788 | fun: &mut F, |
789 | ) { |
790 | let mut target = value; |
791 | |
792 | let last_index = tokens.len().saturating_sub(1); |
793 | for (i, token) in tokens.drain(..).enumerate() { |
794 | let target_once = target; |
795 | let is_last = i == last_index; |
796 | let target_opt = match *target_once { |
797 | Value::Object(ref mut map) => { |
798 | if is_last { |
799 | if let Entry::Occupied(mut e) = map.entry(token) { |
800 | let v = e.insert(Value::Null); |
801 | if let Some(res) = fun(v) { |
802 | e.insert(res); |
803 | } else { |
804 | e.remove(); |
805 | } |
806 | } |
807 | return; |
808 | } |
809 | map.get_mut(&token) |
810 | } |
811 | Value::Array(ref mut vec) => { |
812 | if let Ok(x) = token.parse::<usize>() { |
813 | if is_last { |
814 | let v = std::mem::replace(&mut vec[x], Value::Null); |
815 | if let Some(res) = fun(v) { |
816 | vec[x] = res; |
817 | } else { |
818 | vec.remove(x); |
819 | } |
820 | return; |
821 | } |
822 | vec.get_mut(x) |
823 | } else { |
824 | None |
825 | } |
826 | } |
827 | _ => None, |
828 | }; |
829 | |
830 | if let Some(t) = target_opt { |
831 | target = t; |
832 | } else { |
833 | break; |
834 | } |
835 | } |
836 | } |
837 | |
838 | impl SelectorMut { |
839 | pub fn new() -> Self { |
840 | Self::default() |
841 | } |
842 | |
843 | pub fn str_path(&mut self, path: &str) -> Result<&mut Self, JsonPathError> { |
844 | self.path = Some(Parser::compile(path).map_err(JsonPathError::Path)?); |
845 | Ok(self) |
846 | } |
847 | |
848 | pub fn value(&mut self, value: Value) -> &mut Self { |
849 | self.value = Some(value); |
850 | self |
851 | } |
852 | |
853 | pub fn take(&mut self) -> Option<Value> { |
854 | self.value.take() |
855 | } |
856 | |
857 | fn compute_paths(&self, mut result: Vec<&Value>) -> Vec<Vec<String>> { |
858 | fn _walk( |
859 | origin: &Value, |
860 | target: &mut Vec<&Value>, |
861 | tokens: &mut Vec<String>, |
862 | visited: &mut HashSet<*const Value>, |
863 | visited_order: &mut Vec<Vec<String>>, |
864 | ) -> bool { |
865 | trace!(" {:?}, {:?}" , target, tokens); |
866 | |
867 | if target.is_empty() { |
868 | return true; |
869 | } |
870 | |
871 | target.retain(|t| { |
872 | if std::ptr::eq(origin, *t) { |
873 | if visited.insert(*t) { |
874 | visited_order.push(tokens.to_vec()); |
875 | } |
876 | false |
877 | } else { |
878 | true |
879 | } |
880 | }); |
881 | |
882 | match origin { |
883 | Value::Array(vec) => { |
884 | for (i, v) in vec.iter().enumerate() { |
885 | tokens.push(i.to_string()); |
886 | if _walk(v, target, tokens, visited, visited_order) { |
887 | return true; |
888 | } |
889 | tokens.pop(); |
890 | } |
891 | } |
892 | Value::Object(map) => { |
893 | for (k, v) in map { |
894 | tokens.push(k.clone()); |
895 | if _walk(v, target, tokens, visited, visited_order) { |
896 | return true; |
897 | } |
898 | tokens.pop(); |
899 | } |
900 | } |
901 | _ => {} |
902 | } |
903 | |
904 | false |
905 | } |
906 | |
907 | let mut visited = HashSet::new(); |
908 | let mut visited_order = Vec::new(); |
909 | |
910 | if let Some(origin) = &self.value { |
911 | let mut tokens = Vec::new(); |
912 | _walk( |
913 | origin, |
914 | &mut result, |
915 | &mut tokens, |
916 | &mut visited, |
917 | &mut visited_order, |
918 | ); |
919 | } |
920 | |
921 | visited_order |
922 | } |
923 | |
924 | pub fn delete(&mut self) -> Result<&mut Self, JsonPathError> { |
925 | self.replace_with(&mut |_| Some(Value::Null)) |
926 | } |
927 | |
928 | pub fn remove(&mut self) -> Result<&mut Self, JsonPathError> { |
929 | self.replace_with(&mut |_| None) |
930 | } |
931 | |
932 | fn select(&self) -> Result<Vec<&Value>, JsonPathError> { |
933 | if let Some(node) = &self.path { |
934 | let mut selector = Selector::default(); |
935 | selector.compiled_path(&node); |
936 | |
937 | if let Some(value) = &self.value { |
938 | selector.value(value); |
939 | } |
940 | |
941 | Ok(selector.select()?) |
942 | } else { |
943 | Err(JsonPathError::EmptyPath) |
944 | } |
945 | } |
946 | |
947 | pub fn replace_with<F: FnMut(Value) -> Option<Value>>( |
948 | &mut self, |
949 | fun: &mut F, |
950 | ) -> Result<&mut Self, JsonPathError> { |
951 | let paths = { |
952 | let result = self.select()?; |
953 | self.compute_paths(result) |
954 | }; |
955 | |
956 | if let Some(ref mut value) = &mut self.value { |
957 | for tokens in paths { |
958 | replace_value(tokens, value, fun); |
959 | } |
960 | } |
961 | |
962 | Ok(self) |
963 | } |
964 | } |
965 | |
966 | |
967 | #[cfg (test)] |
968 | mod select_inner_tests { |
969 | use serde_json::Value; |
970 | |
971 | #[test ] |
972 | fn to_f64_i64() { |
973 | let number = 0_i64; |
974 | let v: Value = serde_json::from_str(&format!(" {}" , number)).unwrap(); |
975 | if let Value::Number(n) = v { |
976 | assert_eq!((super::to_f64(&n) - number as f64).abs() == 0_f64, true); |
977 | } else { |
978 | panic!(); |
979 | } |
980 | } |
981 | |
982 | #[test ] |
983 | fn to_f64_f64() { |
984 | let number = 0.1_f64; |
985 | let v: Value = serde_json::from_str(&format!(" {}" , number)).unwrap(); |
986 | if let Value::Number(n) = v { |
987 | assert_eq!((super::to_f64(&n) - number).abs() == 0_f64, true); |
988 | } else { |
989 | panic!(); |
990 | } |
991 | } |
992 | |
993 | #[test ] |
994 | fn to_f64_u64() { |
995 | let number = u64::max_value(); |
996 | let v: Value = serde_json::from_str(&format!(" {}" , number)).unwrap(); |
997 | if let Value::Number(n) = v { |
998 | assert_eq!((super::to_f64(&n) - number as f64).abs() == 0_f64, true); |
999 | } else { |
1000 | panic!(); |
1001 | } |
1002 | } |
1003 | } |