Skip to content

Commit 5c330cd

Browse files
authored
Merge pull request jsonpath-standard#3 from glyn/refactor
Refactor
2 parents ce7ffb7 + 59a4384 commit 5c330cd

File tree

4 files changed

+35
-25
lines changed

4 files changed

+35
-25
lines changed

src/matchers.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ use serde_json::Value;
99
// Matcher maps a node to a list of nodes. If the input node is not matched by the matcher or
1010
// the matcher does not select any subnodes of the input node, then the result is empty.
1111
pub trait Matcher {
12-
fn select(&self, node: Value) -> Vec<Value>;
12+
fn select<'a>(&self, node: &'a Value) -> Vec<&'a Value>;
1313
}
1414

1515
pub struct RootSelector {}
1616

1717
impl Matcher for RootSelector {
18-
fn select(&self, node: Value) -> Vec<Value> {
18+
fn select<'a>(&self, node: &'a Value) -> Vec<&'a Value> {
1919
let mut results = Vec::new();
2020
results.push(node);
2121
results

src/parser.rs

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -38,21 +38,18 @@ pub fn parse(selector: &str) -> Result<Box<dyn Path>, String> {
3838
}
3939

4040
impl Path for SelectorPath<'_> {
41-
fn find(&self, document: Value) -> Result<Vec<Value>, FindError> {
42-
let mut nodes = Vec::new();
43-
nodes.push(document);
44-
45-
// pass nodes through each matcher in turn
46-
for m in self.matchers.clone().into_iter() {
47-
let mut selected = Vec::new();
48-
for n in nodes.clone().into_iter() {
49-
for r in m.select(n).into_iter() {
50-
selected.push(r);
51-
}
52-
}
53-
nodes = selected;
54-
}
55-
56-
Ok(nodes)
41+
fn find<'a>(&self, document: &'a Value) -> Result<Vec<&'a Value>, FindError> {
42+
// pass nodes, starting with document alone, through each matcher in turn
43+
Ok((&self.matchers)
44+
.iter()
45+
.fold(doc_node(document), |nodes, matcher| {
46+
nodes.iter().flat_map(|node| matcher.select(node)).collect()
47+
}))
5748
}
5849
}
50+
51+
fn doc_node<'a>(document: &'a Value) -> Vec<&'a Value> {
52+
let mut nodes = Vec::new();
53+
nodes.push(document);
54+
nodes
55+
}

src/path.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@ pub enum FindError {
1111
}
1212

1313
pub trait Path {
14-
fn find(&self, document: Value) -> Result<Vec<Value>, FindError>;
14+
fn find<'a>(&self, document: &'a Value) -> Result<Vec<&'a Value>, FindError>;
1515
}

tests/cts.rs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,12 @@ mod tests {
5454

5555
if let Ok(p) = path {
5656
if let Ok(result) =
57-
p.find(as_json_value(&t.document).expect("invalid document"))
57+
p.find(&as_json_value(t.document).expect("invalid document"))
5858
{
59-
if result != as_json_value_array(&t.result).expect("invalid result") {
59+
if !equal(
60+
&result,
61+
as_json_value_array(&t.result).expect("invalid result"),
62+
) {
6063
assert!(
6164
false,
6265
"incorrect result, expected: {:?}, got: {:?}",
@@ -76,6 +79,16 @@ mod tests {
7679
assert!(errors.is_empty())
7780
}
7881

82+
fn equal(actual: &Vec<&serde_json::Value>, expected: Vec<serde_json::Value>) -> bool {
83+
if actual.len() != expected.len() {
84+
false
85+
} else {
86+
(0..actual.len()).fold(true, |result, item| {
87+
result && actual[item] == &expected[item]
88+
})
89+
}
90+
}
91+
7992
fn as_json(v: &serde_yaml::Value) -> Result<String, String> {
8093
match v {
8194
serde_yaml::Value::Null => Ok("null".to_string()),
@@ -106,11 +119,11 @@ mod tests {
106119
}
107120
}
108121

109-
fn as_json_value(v: &serde_yaml::Value) -> Result<serde_json::Value, String> {
122+
fn as_json_value(v: serde_yaml::Value) -> Result<serde_json::Value, String> {
110123
match v {
111124
serde_yaml::Value::Null => Ok(serde_json::Value::Null),
112125

113-
serde_yaml::Value::Bool(b) => Ok(serde_json::Value::Bool(*b)),
126+
serde_yaml::Value::Bool(b) => Ok(serde_json::Value::Bool(b)),
114127

115128
serde_yaml::Value::Number(num) => {
116129
Ok(serde_json::Value::Number(yaml_number_as_json(num.clone())))
@@ -129,7 +142,7 @@ mod tests {
129142
let object_members = map.iter().map(|(k, v)| {
130143
(
131144
serde_yaml::to_string(k).expect("non-string mapping key"),
132-
as_json_value(v).expect("invalid map value"),
145+
as_json_value(v.clone()).expect("invalid map value"),
133146
)
134147
});
135148
Ok(serde_json::Value::Object(object_members.collect()))
@@ -142,7 +155,7 @@ mod tests {
142155
serde_yaml::Value::Sequence(seq) => {
143156
let array_elements = seq
144157
.into_iter()
145-
.map(|v| as_json_value(v).expect("invalid sequence element"));
158+
.map(|v| as_json_value(v.clone()).expect("invalid sequence element"));
146159
Ok(array_elements.collect())
147160
}
148161
_ => Err("not a sequence".to_string()),

0 commit comments

Comments
 (0)