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"}
]);
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]

View File

@ -169,7 +169,7 @@ impl ValueFilter {
pub fn step_in_num(&mut self, key: &f64) -> &ValueWrapper {
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 filter_mode = self.filter_mode;
@ -213,6 +213,11 @@ impl ValueFilter {
.filter(|v| !v.is_null())
.collect();
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() {
self.filter_stack.push(ValueFilter::new(v, false, false));
self.filter_stack.push(ValueFilter::new(v, is_leaves, false));
} else {
match self.filter_stack.last_mut() {
Some(vf) => {
vf.vw.set_leaves(is_leaves);
if v.is_null() {
vf.vw.replace(v);
} else if vf.vw.is_array() {
@ -403,7 +409,7 @@ impl JsonValueFilter {
match self.filter_stack.last_mut() {
Some(vf) => {
match self.token_stack.pop() {
Some(ParseToken::In) => {
Some(ParseToken::In) | Some(ParseToken::Array) => {
vf.step_in_string(&key);
}
Some(ParseToken::Leaves) => {
@ -447,17 +453,18 @@ impl JsonValueFilter {
}
}
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() {
Some(mut vf) => {
let is_leaves = vf.vw.is_leaves();
match vf.vw.get_val_mut() {
Value::Null | Value::Bool(false) => {
self.replace_filter_stack(Value::Null);
self.replace_filter_stack(Value::Null, is_leaves);
}
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)]
pub struct ValueWrapper {
val: Value,
leaves: bool,
is_leaves: bool,
}
impl ValueWrapper {
pub fn new(val: Value, leaves: bool) -> Self {
ValueWrapper { val, leaves }
ValueWrapper { val, is_leaves: leaves }
}
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 {

View File

@ -183,6 +183,11 @@ impl<'a> Parser<'a> {
Ok(Token::Asterisk(_)) => {
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)
}
@ -774,6 +779,14 @@ mod tests {
ParseToken::All
]));
assert_eq!(run("$..[0]"), Ok(vec![
ParseToken::Absolute,
ParseToken::Leaves,
ParseToken::Array,
ParseToken::Number(0.0),
ParseToken::ArrayEof
]));
match run("$.") {
Ok(_) => panic!(),
_ => {}