array keys

This commit is contained in:
freestrings
2019-06-18 11:46:24 +09:00
parent 74666d264e
commit de97e2f95a
5 changed files with 77 additions and 24 deletions

View File

@ -693,20 +693,22 @@ impl<'a, 'b> Selector<'a, 'b> {
debug!("next_from_current_with_num : {:?}, {:?}", &index, self.current);
}
fn next_from_current_with_str(&mut self, key: &str) {
fn _collect<'a>(v: &'a Value, tmp: &mut Vec<&'a Value>, key: &str, visited: &mut HashSet<*const Value>) {
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 {
Value::Object(map) => {
if let Some(v) = map.get(key) {
let ptr = v as *const Value;
if !visited.contains(&ptr) {
visited.insert(ptr);
tmp.push(v)
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, key, visited);
_collect(v, tmp, keys, visited);
}
_ => {}
}
@ -716,12 +718,12 @@ impl<'a, 'b> Selector<'a, 'b> {
let mut tmp = Vec::new();
let mut visited = HashSet::new();
for c in current {
_collect(c, &mut tmp, key, &mut visited);
_collect(c, &mut tmp, keys, &mut visited);
}
self.current = Some(tmp);
}
debug!("next_from_current_with_str : {}, {:?}", key, self.current);
debug!("next_from_current_with_str : {:?}, {:?}", keys, self.current);
}
fn next_all_from_current(&mut self) {
@ -838,7 +840,7 @@ impl<'a, 'b> NodeVisitor for Selector<'a, 'b> {
self.next_from_current_with_num(to_f64(&n));
}
ExprTerm::String(key) => {
self.next_from_current_with_str(&key);
self.next_from_current_with_str(&vec![key]);
}
ExprTerm::Json(_, v) => {
if v.is_empty() {
@ -886,7 +888,7 @@ impl<'a, 'b> NodeVisitor for Selector<'a, 'b> {
self.all_from_current_with_str(key.as_str())
}
ParseToken::In => {
self.next_from_current_with_str(key.as_str())
self.next_from_current_with_str(&vec![key.clone()])
}
_ => {}
}
@ -905,6 +907,17 @@ impl<'a, 'b> NodeVisitor for Selector<'a, 'b> {
_ => {}
}
}
ParseToken::Keys(keys) => {
if !self.terms.is_empty() {
unimplemented!("keys in filter");
}
if let Some(ParseToken::Array) = self.tokens.pop() {
self.next_from_current_with_str(keys);
} else {
unreachable!();
}
}
ParseToken::Number(v) => {
self.terms.push(Some(ExprTerm::Number(Number::from_f64(*v).unwrap())));
}