mirror of
https://github.com/fluencelabs/jsonpath
synced 2025-03-15 15:00:51 +00:00
Bracket notation after recursive descent does not recurse #40
This commit is contained in:
parent
67cc6447a8
commit
241a7f482d
@ -2,8 +2,8 @@ use std::collections::HashSet;
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use array_tool::vec::{Intersect, Union};
|
use array_tool::vec::{Intersect, Union};
|
||||||
use serde_json::map::Entry;
|
|
||||||
use serde_json::{Number, Value};
|
use serde_json::{Number, Value};
|
||||||
|
use serde_json::map::Entry;
|
||||||
|
|
||||||
use parser::*;
|
use parser::*;
|
||||||
|
|
||||||
@ -390,6 +390,18 @@ impl<'a> Into<ExprTerm<'a>> for &Vec<&'a Value> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn walk_all_with_num<'a>(vec: &[&'a Value], tmp: &mut Vec<&'a Value>, index: f64) {
|
||||||
|
walk(vec, tmp, &|v| if v.is_array() {
|
||||||
|
if let Some(item) = v.get(index as usize) {
|
||||||
|
Some(vec![item])
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
fn walk_all_with_str<'a>(vec: &[&'a Value], tmp: &mut Vec<&'a Value>, key: &str, is_filter: bool) {
|
fn walk_all_with_str<'a>(vec: &[&'a Value], tmp: &mut Vec<&'a Value>, key: &str, is_filter: bool) {
|
||||||
if is_filter {
|
if is_filter {
|
||||||
walk(vec, tmp, &|v| match v {
|
walk(vec, tmp, &|v| match v {
|
||||||
@ -833,6 +845,16 @@ impl<'a, 'b> Selector<'a, 'b> {
|
|||||||
debug!("all_from_current_with_str: {}, {:?}", key, self.current);
|
debug!("all_from_current_with_str: {}, {:?}", key, self.current);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn all_from_current_with_num(&mut self, index: f64) {
|
||||||
|
if let Some(current) = self.current.take() {
|
||||||
|
let mut tmp = Vec::new();
|
||||||
|
|
||||||
|
walk_all_with_num(¤t, &mut tmp, index);
|
||||||
|
self.current = Some(tmp);
|
||||||
|
}
|
||||||
|
debug!("all_from_current_with_num: {}, {:?}", index, self.current);
|
||||||
|
}
|
||||||
|
|
||||||
fn compute_absolute_path_filter(&mut self, token: &ParseToken) -> bool {
|
fn compute_absolute_path_filter(&mut self, token: &ParseToken) -> bool {
|
||||||
if !self.selectors.is_empty() {
|
if !self.selectors.is_empty() {
|
||||||
match token {
|
match token {
|
||||||
@ -895,7 +917,7 @@ impl<'a, 'b> Selector<'a, 'b> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn visit_array_eof(&mut self) {
|
fn visit_array_eof(&mut self) {
|
||||||
if self.is_nested_array() {
|
if self.is_last_before_token_match(ParseToken::Array) {
|
||||||
if let Some(Some(e)) = self.terms.pop() {
|
if let Some(Some(e)) = self.terms.pop() {
|
||||||
if let ExprTerm::String(key) = e {
|
if let ExprTerm::String(key) = e {
|
||||||
self.next_in_filter_with_str(&key);
|
self.next_in_filter_with_str(&key);
|
||||||
@ -907,6 +929,20 @@ impl<'a, 'b> Selector<'a, 'b> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.is_last_before_token_match(ParseToken::Leaves) {
|
||||||
|
self.tokens.pop();
|
||||||
|
self.tokens.pop();
|
||||||
|
if let Some(Some(e)) = self.terms.pop() {
|
||||||
|
if let ExprTerm::Number(n) = &e {
|
||||||
|
self.all_from_current_with_num(to_f64(n));
|
||||||
|
self.terms.pop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.terms.push(Some(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(Some(e)) = self.terms.pop() {
|
if let Some(Some(e)) = self.terms.pop() {
|
||||||
match e {
|
match e {
|
||||||
ExprTerm::Number(n) => {
|
ExprTerm::Number(n) => {
|
||||||
@ -934,6 +970,14 @@ impl<'a, 'b> Selector<'a, 'b> {
|
|||||||
self.tokens.pop();
|
self.tokens.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_last_before_token_match(&mut self, token: ParseToken) -> bool {
|
||||||
|
if self.tokens.len() > 1 {
|
||||||
|
return &token == &self.tokens[self.tokens.len() - 2];
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
fn visit_all(&mut self) {
|
fn visit_all(&mut self) {
|
||||||
if let Some(ParseToken::Array) = self.tokens.last() {
|
if let Some(ParseToken::Array) = self.tokens.last() {
|
||||||
self.tokens.pop();
|
self.tokens.pop();
|
||||||
@ -954,21 +998,6 @@ impl<'a, 'b> Selector<'a, 'b> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_nested_array(&mut self) -> bool {
|
|
||||||
let mut is_nested_array = false;
|
|
||||||
|
|
||||||
if let Some(t) = self.tokens.pop() {
|
|
||||||
if let ParseToken::Array = t {
|
|
||||||
if let Some(ParseToken::Array) = self.tokens.last() {
|
|
||||||
is_nested_array = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.tokens.push(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
is_nested_array
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_key(&mut self, key: &str) {
|
fn visit_key(&mut self, key: &str) {
|
||||||
if let Some(ParseToken::Array) = self.tokens.last() {
|
if let Some(ParseToken::Array) = self.tokens.last() {
|
||||||
self.terms.push(Some(ExprTerm::String(key.to_string())));
|
self.terms.push(Some(ExprTerm::String(key.to_string())));
|
||||||
|
@ -216,3 +216,38 @@ fn array_multiple_key() {
|
|||||||
json!(["blue", "Leonor Herman"]),
|
json!(["blue", "Leonor Herman"]),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn bugs40_bracket_notation_after_recursive_descent() {
|
||||||
|
setup();
|
||||||
|
|
||||||
|
select_and_then_compare(
|
||||||
|
"$..[0]",
|
||||||
|
json!([
|
||||||
|
"first",
|
||||||
|
{
|
||||||
|
"key": [
|
||||||
|
"first nested",
|
||||||
|
{
|
||||||
|
"more": [
|
||||||
|
{"nested": ["deepest", "second"]},
|
||||||
|
["more", "values"]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]),
|
||||||
|
json!([
|
||||||
|
"first",
|
||||||
|
"first nested",
|
||||||
|
{
|
||||||
|
"nested" : [
|
||||||
|
"deepest",
|
||||||
|
"second"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"deepest",
|
||||||
|
"more"
|
||||||
|
]),
|
||||||
|
);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user