From 76a5c27347f470da17ff18b294632f4daa9418fb Mon Sep 17 00:00:00 2001 From: freestrings Date: Mon, 25 Feb 2019 14:51:28 +0900 Subject: [PATCH] enable preserve_order --- .../filter_example__trace.xml | 14 ++++ Cargo.toml | 4 +- src/jsonpath/json_filter.rs | 82 ++++++++++++++----- 3 files changed, 76 insertions(+), 24 deletions(-) create mode 100644 .idea/runConfigurations/filter_example__trace.xml diff --git a/.idea/runConfigurations/filter_example__trace.xml b/.idea/runConfigurations/filter_example__trace.xml new file mode 100644 index 0000000..e3bae76 --- /dev/null +++ b/.idea/runConfigurations/filter_example__trace.xml @@ -0,0 +1,14 @@ + + + + \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 9b12d63..0450cd5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ authors = ["freestrings "] log = "0.4" env_logger = "0.6.0" serde = "1.0" -serde_json = "1.0" +serde_json = { version = "1.0", features = ["preserve_order"] } [dev-dependencies] -bencher = "0.1.5" \ No newline at end of file +bencher = "0.1.5" diff --git a/src/jsonpath/json_filter.rs b/src/jsonpath/json_filter.rs index ef298da..06e7c13 100644 --- a/src/jsonpath/json_filter.rs +++ b/src/jsonpath/json_filter.rs @@ -368,18 +368,36 @@ impl ValueFilter { &self.vw } - fn step_leaves(&mut self, key: &String) -> &ValueWrapper { + fn step_leaves_str(&mut self, key: &str) -> &ValueWrapper { + self.step_leaves_string(&key.to_string()) + } + + fn step_leaves_string(&mut self, key: &String) -> &ValueWrapper { debug!("step_leaves"); - let mut vw = ValueWrapper::new(Value::Null); - loop { - vw.push(self.step_in_string(key).clone_val()); - if let Value::Null = self.vw.val() { - break; + let mut buf: Vec = Vec::new(); + + fn _fn(key: &String, v: &Value, buf: &mut Vec) { + match v { + Value::Array(vec) => { + for i in vec { + _fn(key, i, buf); + } + } + Value::Object(v) => { + for (k, v) in v.into_iter() { + if key == k { + buf.push(v.clone()); + } + _fn(key, v, buf); + } + } + _ => {} } } + _fn(key, &self.vw.val, &mut buf); self.last_key = Some(ValueFilterKey::String(key.clone())); - self.vw = vw; + self.vw = ValueWrapper::new(Value::Array(buf)); &self.vw } @@ -592,7 +610,7 @@ impl NodeVisitor for JsonValueFilter { vf.step_in_string(&key); } Some(ParseToken::Leaves) => { - vf.step_leaves(&key); + vf.step_leaves_string(&key); } _ => {} } @@ -1064,6 +1082,19 @@ mod tests { ]); assert_eq!(&friends, ¤t.val); } + let mut jf = new_value_filter("./benches/data_obj.json"); + { + let current = jf.step_leaves_str("name"); + let names = json!([ + "Leonor Herman", + "Millicent Norman", + "Vincent Cannon", + "Gray Berry", + "Vincent Cannon", + "Gray Berry" + ]); + assert_eq!(&names, ¤t.val); + } } #[test] @@ -1148,17 +1179,13 @@ mod tests { ]); assert_eq!(&friends, jf.current_value()); - // - // TODO 원본 json 순서여야 하나? => serde_json preserve_order 피처를 enable 시켜야 함. - // + // TODO order let jf = do_filter("$.friends[?(@.id >= 2 || @.id == 1)]", "./benches/data_obj.json"); - let mut map = HashMap::new(); - let mut val = jf.current_value().clone(); - val.as_array_mut().unwrap().iter_mut().enumerate().for_each(|(i, v)| { - map.insert(i, v.take()); - }); - let friends = vec![map.get_mut(&0).unwrap().take(), map.get_mut(&1).unwrap().take()]; - assert_eq!(&Value::Array(friends), jf.current_value()); + let friends = json!([ + { "id" : 2, "name" : "Gray Berry" }, + { "id" : 1, "name" : "Vincent Cannon" } + ]); + assert_eq!(&friends, jf.current_value()); let jf = do_filter("$.friends[?( (@.id >= 2 || @.id == 1) && @.id == 0)]", "./benches/data_obj.json"); assert_eq!(&Value::Null, jf.current_value()); @@ -1167,12 +1194,23 @@ mod tests { #[test] fn example() { let jf = do_filter("$.store.book[*].author", "./benches/example.json"); + let ret = json!(["Nigel Rees","Evelyn Waugh","Herman Melville","J. R. R. Tolkien"]); + assert_eq!(&ret, jf.current_value()); + + let jf = do_filter("$..author", "./benches/example.json"); + assert_eq!(&ret, jf.current_value()); + + let jf = do_filter("$.store.*", "./benches/example.json"); let ret = json!([ - "Nigel Rees", - "Evelyn Waugh", - "Herman Melville", - "J. R. R. Tolkien" + [ + {"category" : "reference", "author" : "Nigel Rees","title" : "Sayings of the Century", "price" : 8.95}, + {"category" : "fiction", "author" : "Evelyn Waugh","title" : "Sword of Honour","price" : 12.99}, + {"category" : "fiction", "author" : "Herman Melville","title" : "Moby Dick","isbn" : "0-553-21311-3","price" : 8.99}, + {"category" : "fiction", "author" : "J. R. R. Tolkien","title" : "The Lord of the Rings","isbn" : "0-395-19395-8","price" : 22.99} + ], + {"color" : "red","price" : 19.95}, ]); assert_eq!(&ret, jf.current_value()); } + } \ No newline at end of file