fix wildcard filter

This commit is contained in:
freestrings 2019-06-23 18:21:59 +09:00
parent d384079842
commit 053be432f2
2 changed files with 89 additions and 57 deletions

View File

@ -758,39 +758,20 @@ impl<'a, 'b> Selector<'a, 'b> {
}
fn next_from_current_with_str(&mut self, keys: &Vec<String>) {
fn _collect<'a>(
v: &'a Value,
tmp: &mut Vec<&'a Value>,
keys: &Vec<String>,
visited: &mut HashSet<*const Value>,
) {
match v {
if let Some(current) = self.current.take() {
let mut tmp = Vec::new();
for c in current {
match c {
Value::Object(map) => {
for key in keys {
if let Some(v) = map.get(key) {
let ptr = v as *const Value;
if !visited.contains(&ptr) {
visited.insert(ptr);
tmp.push(v)
}
}
}
}
Value::Array(vec) => {
for v in vec {
_collect(v, tmp, keys, visited);
}
}
_ => {}
}
}
if let Some(current) = self.current.take() {
let mut tmp = Vec::new();
let mut visited = HashSet::new();
for c in current {
_collect(c, &mut tmp, keys, &mut visited);
}
self.current = Some(tmp);
}
@ -801,8 +782,10 @@ impl<'a, 'b> Selector<'a, 'b> {
}
fn next_all_from_current(&mut self) {
fn _collect<'a>(v: &'a Value, tmp: &mut Vec<&'a Value>) {
match v {
if let Some(current) = self.current.take() {
let mut tmp = Vec::new();
for c in current {
match c {
Value::Object(map) => {
for (_, v) in map {
tmp.push(v)
@ -810,18 +793,12 @@ impl<'a, 'b> Selector<'a, 'b> {
}
Value::Array(vec) => {
for v in vec {
_collect(v, tmp);
tmp.push(v);
}
}
_ => {}
}
}
if let Some(current) = self.current.take() {
let mut tmp = Vec::new();
for c in current {
_collect(c, &mut tmp);
}
self.current = Some(tmp);
}
@ -934,7 +911,15 @@ impl<'a, 'b> NodeVisitor for Selector<'a, 'b> {
self.tokens.pop();
}
ParseToken::All => match self.tokens.last() {
ParseToken::All => {
match self.tokens.last() {
Some(ParseToken::Array) => {
self.tokens.pop();
}
_ => {}
}
match self.tokens.last() {
Some(ParseToken::Leaves) => {
self.tokens.pop();
self.all_from_current();
@ -943,8 +928,11 @@ impl<'a, 'b> NodeVisitor for Selector<'a, 'b> {
self.tokens.pop();
self.next_all_from_current();
}
_ => {}
},
_ => {
self.next_all_from_current();
}
}
}
ParseToken::Bool(b) => {
self.terms.push(Some(ExprTerm::Bool(*b)));
}

View File

@ -619,3 +619,47 @@ fn quote() {
json!(["value"]),
);
}
#[test]
fn all_filter() {
setup();
for path in vec![r#"$.*"#, r#"$[*]"#] {
select_and_then_compare(
path,
json!(["string", 42, { "key": "value" }, [0, 1]]),
json!(["string", 42, { "key": "value" }, [0, 1]]),
);
}
for path in vec![r#"$..*"#, r#"$..[*]"#] {
select_and_then_compare(
path,
json!(["string", 42, { "key": "value" }, [0, 1]]),
json!([ "string", 42, { "key" : "value" }, [ 0, 1 ], "value", 0, 1 ]),
);
}
for path in vec![r#"$.*.*"#, r#"$[*].*"#, r#"$.*[*]"#, r#"$[*][*]"#] {
select_and_then_compare(
path,
json!(["string", 42, { "key": "value" }, [0, 1]]),
json!(["value", 0, 1]),
);
}
for path in vec![r#"$..friends.*"#, r#"$[*].friends.*"#] {
select_and_then_compare(
path,
read_json("./benches/data_array.json"),
json!([
{ "id" : 0, "name" : "Millicent Norman" },
{ "id" : 1, "name" : "Vincent Cannon" },
{ "id" : 2, "name" : "Gray Berry" },
{ "id" : 0, "name" : "Tillman Mckay" },
{ "id" : 1, "name" : "Rivera Berg" },
{ "id" : 2, "name" : "Rosetta Erickson" }
]),
);
}
}