array example 적용

This commit is contained in:
freestrings 2019-02-27 12:12:14 +09:00
parent 87a226451a
commit 7bf3bb59b0
5 changed files with 64 additions and 10 deletions

View File

@ -0,0 +1,14 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="filter_array - trace" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
<option name="channel" value="DEFAULT" />
<option name="command" value="test --package rs-jsonpath --lib jsonpath::json_filter::tests::array -- --exact" />
<option name="allFeatures" value="false" />
<option name="nocapture" value="true" />
<option name="backtrace" value="NO" />
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
<envs>
<env name="RUST_LOG" value="trace" />
</envs>
<method v="2" />
</configuration>
</component>

View File

@ -112,6 +112,22 @@ mod tests {
{"id": 0, "name": "Millicent Norman"} {"id": 0, "name": "Millicent Norman"}
]); ]);
assert_eq!(&friends, jf.current_value()); assert_eq!(&friends, jf.current_value());
let jf = do_filter("$..friends[2].name", "./benches/data_obj.json");
let friends = json!(["Gray Berry", "Gray Berry"]);
assert_eq!(&friends, jf.current_value());
let jf = do_filter("$..friends[*].name", "./benches/data_obj.json");
let friends = json!(["Vincent Cannon","Gray Berry","Millicent Norman","Vincent Cannon","Gray Berry"]);
assert_eq!(&friends, jf.current_value());
let jf = do_filter("$['school']['friends'][*].['name']", "./benches/data_obj.json");
let friends = json!(["Millicent Norman","Vincent Cannon","Gray Berry"]);
assert_eq!(&friends, jf.current_value());
let jf = do_filter("$['school']['friends'][0].['name']", "./benches/data_obj.json");
let friends = json!("Millicent Norman");
assert_eq!(&friends, jf.current_value());
} }
#[test] #[test]

View File

@ -169,7 +169,7 @@ impl ValueFilter {
pub fn step_in_num(&mut self, key: &f64) -> &ValueWrapper { pub fn step_in_num(&mut self, key: &f64) -> &ValueWrapper {
debug!("step_in_num"); debug!("step_in_num");
trace!("step_in_num - before: {} - {:?}", self.filter_mode, self.vw.get_val()); trace!("step_in_num - before: leaves {}, filterMode {} - {:?}", self.vw.is_leaves(), self.filter_mode, self.vw.get_val());
let v = if self.vw.is_leaves() { let v = if self.vw.is_leaves() {
let filter_mode = self.filter_mode; let filter_mode = self.filter_mode;
@ -213,6 +213,11 @@ impl ValueFilter {
.filter(|v| !v.is_null()) .filter(|v| !v.is_null())
.collect(); .collect();
buf.append(&mut ret); buf.append(&mut ret);
} else {
match item.get_mut(key) {
Some(v) => buf.push(v.take()),
_ => {}
}
} }
} }
@ -294,12 +299,13 @@ impl JsonValueFilter {
} }
} }
fn replace_filter_stack(&mut self, v: Value) { fn replace_filter_stack(&mut self, v: Value, is_leaves: bool) {
if self.filter_stack.is_empty() { if self.filter_stack.is_empty() {
self.filter_stack.push(ValueFilter::new(v, false, false)); self.filter_stack.push(ValueFilter::new(v, is_leaves, false));
} else { } else {
match self.filter_stack.last_mut() { match self.filter_stack.last_mut() {
Some(vf) => { Some(vf) => {
vf.vw.set_leaves(is_leaves);
if v.is_null() { if v.is_null() {
vf.vw.replace(v); vf.vw.replace(v);
} else if vf.vw.is_array() { } else if vf.vw.is_array() {
@ -403,7 +409,7 @@ impl JsonValueFilter {
match self.filter_stack.last_mut() { match self.filter_stack.last_mut() {
Some(vf) => { Some(vf) => {
match self.token_stack.pop() { match self.token_stack.pop() {
Some(ParseToken::In) => { Some(ParseToken::In) | Some(ParseToken::Array) => {
vf.step_in_string(&key); vf.step_in_string(&key);
} }
Some(ParseToken::Leaves) => { Some(ParseToken::Leaves) => {
@ -447,17 +453,18 @@ impl JsonValueFilter {
} }
} }
Some(TermContext::Json(_, mut vw)) => { Some(TermContext::Json(_, mut vw)) => {
self.replace_filter_stack(vw.get_val_mut().take()); self.replace_filter_stack(vw.get_val_mut().take(), vw.is_leaves());
} }
_ => { _ => {
match self.filter_stack.pop() { match self.filter_stack.pop() {
Some(mut vf) => { Some(mut vf) => {
let is_leaves = vf.vw.is_leaves();
match vf.vw.get_val_mut() { match vf.vw.get_val_mut() {
Value::Null | Value::Bool(false) => { Value::Null | Value::Bool(false) => {
self.replace_filter_stack(Value::Null); self.replace_filter_stack(Value::Null, is_leaves);
} }
other => { other => {
self.replace_filter_stack(other.take()); self.replace_filter_stack(other.take(), is_leaves);
} }
} }
} }

View File

@ -8,16 +8,20 @@ use super::value_filter::*;
#[derive(Debug)] #[derive(Debug)]
pub struct ValueWrapper { pub struct ValueWrapper {
val: Value, val: Value,
leaves: bool, is_leaves: bool,
} }
impl ValueWrapper { impl ValueWrapper {
pub fn new(val: Value, leaves: bool) -> Self { pub fn new(val: Value, leaves: bool) -> Self {
ValueWrapper { val, leaves } ValueWrapper { val, is_leaves: leaves }
} }
pub fn is_leaves(&self) -> bool { pub fn is_leaves(&self) -> bool {
self.leaves self.is_leaves
}
pub fn set_leaves(&mut self, is_leaves: bool) {
self.is_leaves = is_leaves;
} }
pub fn cmp(&mut self, other: &mut ValueWrapper, cmp_type: CmpType) -> TermContext { pub fn cmp(&mut self, other: &mut ValueWrapper, cmp_type: CmpType) -> TermContext {

View File

@ -183,6 +183,11 @@ impl<'a> Parser<'a> {
Ok(Token::Asterisk(_)) => { Ok(Token::Asterisk(_)) => {
self.path_leaves_all(prev) self.path_leaves_all(prev)
} }
Ok(Token::OpenArray(_)) => {
let mut leaves_node = self.node(ParseToken::Leaves);
leaves_node.left = Some(Box::new(prev));
Ok(self.paths(leaves_node)?)
}
_ => { _ => {
self.path_leaves_key(prev) self.path_leaves_key(prev)
} }
@ -774,6 +779,14 @@ mod tests {
ParseToken::All ParseToken::All
])); ]));
assert_eq!(run("$..[0]"), Ok(vec![
ParseToken::Absolute,
ParseToken::Leaves,
ParseToken::Array,
ParseToken::Number(0.0),
ParseToken::ArrayEof
]));
match run("$.") { match run("$.") {
Ok(_) => panic!(), Ok(_) => panic!(),
_ => {} _ => {}