mirror of
https://github.com/Orange-OpenSource/hurl.git
synced 2024-12-25 20:12:14 +03:00
Split jsonpath index selector (unique/multiple index)
- specify one index to return one element - specify two or more index to return a collection of elements
This commit is contained in:
parent
a97b172e58
commit
479e9e97cd
@ -28,7 +28,8 @@ pub struct Query {
|
|||||||
pub enum Selector {
|
pub enum Selector {
|
||||||
Wildcard,
|
Wildcard,
|
||||||
NameChild(String),
|
NameChild(String),
|
||||||
ArrayIndex(Vec<usize>), // one or more indexes (separated by comma)
|
ArrayIndex(usize), // one unique index
|
||||||
|
ArrayIndices(Vec<usize>), // two or more indexes (separated by comma)
|
||||||
ArraySlice(Slice),
|
ArraySlice(Slice),
|
||||||
ArrayWildcard,
|
ArrayWildcard,
|
||||||
Filter(Predicate),
|
Filter(Predicate),
|
||||||
|
@ -61,6 +61,9 @@ impl Selector {
|
|||||||
Selector::NameChild(field) => root
|
Selector::NameChild(field) => root
|
||||||
.get(field)
|
.get(field)
|
||||||
.map(|result| JsonpathResult::SingleEntry(result.clone())),
|
.map(|result| JsonpathResult::SingleEntry(result.clone())),
|
||||||
|
Selector::ArrayIndex(index) => root
|
||||||
|
.get(index)
|
||||||
|
.map(|result| JsonpathResult::SingleEntry(result.clone())),
|
||||||
|
|
||||||
// Selectors returning a collection ("indefinite")
|
// Selectors returning a collection ("indefinite")
|
||||||
Selector::Wildcard | Selector::ArrayWildcard => {
|
Selector::Wildcard | Selector::ArrayWildcard => {
|
||||||
@ -163,14 +166,7 @@ impl Selector {
|
|||||||
};
|
};
|
||||||
Some(JsonpathResult::Collection(elements))
|
Some(JsonpathResult::Collection(elements))
|
||||||
}
|
}
|
||||||
|
Selector::ArrayIndices(indexes) => {
|
||||||
// Selectors returning one or the other
|
|
||||||
Selector::ArrayIndex(indexes) => {
|
|
||||||
if indexes.len() == 1 {
|
|
||||||
let index = indexes[0];
|
|
||||||
root.get(index)
|
|
||||||
.map(|result| JsonpathResult::SingleEntry(result.clone()))
|
|
||||||
} else {
|
|
||||||
let mut values = vec![];
|
let mut values = vec![];
|
||||||
for index in indexes {
|
for index in indexes {
|
||||||
if let Some(value) = root.get(index) {
|
if let Some(value) = root.get(index) {
|
||||||
@ -182,7 +178,6 @@ impl Selector {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl Predicate {
|
impl Predicate {
|
||||||
pub fn eval(&self, elem: serde_json::Value) -> bool {
|
pub fn eval(&self, elem: serde_json::Value) -> bool {
|
||||||
@ -322,7 +317,7 @@ mod tests {
|
|||||||
selectors: vec![
|
selectors: vec![
|
||||||
Selector::NameChild("store".to_string()),
|
Selector::NameChild("store".to_string()),
|
||||||
Selector::NameChild("book".to_string()),
|
Selector::NameChild("book".to_string()),
|
||||||
Selector::ArrayIndex(vec![0]),
|
Selector::ArrayIndex(0),
|
||||||
Selector::NameChild("title".to_string()),
|
Selector::NameChild("title".to_string()),
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
@ -401,11 +396,11 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
pub fn test_selector_array_index() {
|
pub fn test_selector_array_index() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Selector::ArrayIndex(vec![0]).eval(&json_books()).unwrap(),
|
Selector::ArrayIndex(0).eval(&json_books()).unwrap(),
|
||||||
JsonpathResult::SingleEntry(json_first_book())
|
JsonpathResult::SingleEntry(json_first_book())
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Selector::ArrayIndex(vec![1, 2])
|
Selector::ArrayIndices(vec![1, 2])
|
||||||
.eval(&json_books())
|
.eval(&json_books())
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
JsonpathResult::Collection(vec![json_second_book(), json_third_book()])
|
JsonpathResult::Collection(vec![json_second_book(), json_third_book()])
|
||||||
@ -458,9 +453,13 @@ mod tests {
|
|||||||
pub fn test_array_index() {
|
pub fn test_array_index() {
|
||||||
let value = json!(["first", "second", "third", "forth", "fifth"]);
|
let value = json!(["first", "second", "third", "forth", "fifth"]);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Selector::ArrayIndex(vec![2]).eval(&value).unwrap(),
|
Selector::ArrayIndex(2).eval(&value).unwrap(),
|
||||||
JsonpathResult::SingleEntry(json!("third"))
|
JsonpathResult::SingleEntry(json!("third"))
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
Selector::ArrayIndices(vec![2, 3]).eval(&value).unwrap(),
|
||||||
|
JsonpathResult::Collection(vec![json!("third"), json!("forth")])
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -50,7 +50,7 @@ fn selector(reader: &mut Reader) -> ParseResult<Selector> {
|
|||||||
selector_wildcard,
|
selector_wildcard,
|
||||||
selector_recursive_wildcard,
|
selector_recursive_wildcard,
|
||||||
selector_recursive_key,
|
selector_recursive_key,
|
||||||
selector_array_index,
|
selector_array_index_or_array_indices,
|
||||||
selector_array_wildcard,
|
selector_array_wildcard,
|
||||||
selector_array_slice,
|
selector_array_slice,
|
||||||
selector_object_key_bracket,
|
selector_object_key_bracket,
|
||||||
@ -60,7 +60,7 @@ fn selector(reader: &mut Reader) -> ParseResult<Selector> {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn selector_array_index(reader: &mut Reader) -> Result<Selector, Error> {
|
fn selector_array_index_or_array_indices(reader: &mut Reader) -> Result<Selector, Error> {
|
||||||
try_left_bracket(reader)?;
|
try_left_bracket(reader)?;
|
||||||
let mut indexes = vec![];
|
let mut indexes = vec![];
|
||||||
let i = match natural(reader) {
|
let i = match natural(reader) {
|
||||||
@ -94,7 +94,12 @@ fn selector_array_index(reader: &mut Reader) -> Result<Selector, Error> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
literal("]", reader)?;
|
literal("]", reader)?;
|
||||||
Ok(Selector::ArrayIndex(indexes))
|
let selector = if indexes.len() == 1 {
|
||||||
|
Selector::ArrayIndex(*indexes.first().unwrap())
|
||||||
|
} else {
|
||||||
|
Selector::ArrayIndices(indexes)
|
||||||
|
};
|
||||||
|
Ok(selector)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn selector_array_wildcard(reader: &mut Reader) -> Result<Selector, Error> {
|
fn selector_array_wildcard(reader: &mut Reader) -> Result<Selector, Error> {
|
||||||
@ -312,7 +317,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
pub fn test_query() {
|
pub fn test_query() {
|
||||||
let expected_query = Query {
|
let expected_query = Query {
|
||||||
selectors: vec![Selector::ArrayIndex(vec![2])],
|
selectors: vec![Selector::ArrayIndex(2)],
|
||||||
};
|
};
|
||||||
assert_eq!(query(&mut Reader::new("$[2]")).unwrap(), expected_query);
|
assert_eq!(query(&mut Reader::new("$[2]")).unwrap(), expected_query);
|
||||||
|
|
||||||
@ -338,7 +343,7 @@ mod tests {
|
|||||||
selectors: vec![
|
selectors: vec![
|
||||||
Selector::NameChild("store".to_string()),
|
Selector::NameChild("store".to_string()),
|
||||||
Selector::NameChild("book".to_string()),
|
Selector::NameChild("book".to_string()),
|
||||||
Selector::ArrayIndex(vec![0]),
|
Selector::ArrayIndex(0),
|
||||||
Selector::NameChild("title".to_string()),
|
Selector::NameChild("title".to_string()),
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
@ -354,7 +359,7 @@ mod tests {
|
|||||||
let expected_query = Query {
|
let expected_query = Query {
|
||||||
selectors: vec![
|
selectors: vec![
|
||||||
Selector::RecursiveKey("book".to_string()),
|
Selector::RecursiveKey("book".to_string()),
|
||||||
Selector::ArrayIndex(vec![2]),
|
Selector::ArrayIndex(2),
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@ -423,26 +428,20 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
pub fn test_selector_array_index() {
|
pub fn test_selector_array_index() {
|
||||||
let mut reader = Reader::new("[2]");
|
let mut reader = Reader::new("[2]");
|
||||||
assert_eq!(
|
assert_eq!(selector(&mut reader).unwrap(), Selector::ArrayIndex(2));
|
||||||
selector(&mut reader).unwrap(),
|
|
||||||
Selector::ArrayIndex(vec![2])
|
|
||||||
);
|
|
||||||
assert_eq!(reader.state.cursor, 3);
|
assert_eq!(reader.state.cursor, 3);
|
||||||
|
|
||||||
let mut reader = Reader::new("[0,1]");
|
let mut reader = Reader::new("[0,1]");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
selector(&mut reader).unwrap(),
|
selector(&mut reader).unwrap(),
|
||||||
Selector::ArrayIndex(vec![0, 1])
|
Selector::ArrayIndices(vec![0, 1])
|
||||||
);
|
);
|
||||||
assert_eq!(reader.state.cursor, 5);
|
assert_eq!(reader.state.cursor, 5);
|
||||||
|
|
||||||
// you don't need to keep the exact string
|
// you don't need to keep the exact string
|
||||||
// this is not part of the AST
|
// this is not part of the AST
|
||||||
let mut reader = Reader::new(".[2]");
|
let mut reader = Reader::new(".[2]");
|
||||||
assert_eq!(
|
assert_eq!(selector(&mut reader).unwrap(), Selector::ArrayIndex(2));
|
||||||
selector(&mut reader).unwrap(),
|
|
||||||
Selector::ArrayIndex(vec![2])
|
|
||||||
);
|
|
||||||
assert_eq!(reader.state.cursor, 4);
|
assert_eq!(reader.state.cursor, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user