mirror of
https://github.com/Orange-OpenSource/hurl.git
synced 2024-12-25 12:05:32 +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 {
|
||||
Wildcard,
|
||||
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),
|
||||
ArrayWildcard,
|
||||
Filter(Predicate),
|
||||
|
@ -61,6 +61,9 @@ impl Selector {
|
||||
Selector::NameChild(field) => root
|
||||
.get(field)
|
||||
.map(|result| JsonpathResult::SingleEntry(result.clone())),
|
||||
Selector::ArrayIndex(index) => root
|
||||
.get(index)
|
||||
.map(|result| JsonpathResult::SingleEntry(result.clone())),
|
||||
|
||||
// Selectors returning a collection ("indefinite")
|
||||
Selector::Wildcard | Selector::ArrayWildcard => {
|
||||
@ -163,14 +166,7 @@ impl Selector {
|
||||
};
|
||||
Some(JsonpathResult::Collection(elements))
|
||||
}
|
||||
|
||||
// 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 {
|
||||
Selector::ArrayIndices(indexes) => {
|
||||
let mut values = vec![];
|
||||
for index in indexes {
|
||||
if let Some(value) = root.get(index) {
|
||||
@ -182,7 +178,6 @@ impl Selector {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Predicate {
|
||||
pub fn eval(&self, elem: serde_json::Value) -> bool {
|
||||
@ -322,7 +317,7 @@ mod tests {
|
||||
selectors: vec![
|
||||
Selector::NameChild("store".to_string()),
|
||||
Selector::NameChild("book".to_string()),
|
||||
Selector::ArrayIndex(vec![0]),
|
||||
Selector::ArrayIndex(0),
|
||||
Selector::NameChild("title".to_string()),
|
||||
],
|
||||
};
|
||||
@ -401,11 +396,11 @@ mod tests {
|
||||
#[test]
|
||||
pub fn test_selector_array_index() {
|
||||
assert_eq!(
|
||||
Selector::ArrayIndex(vec![0]).eval(&json_books()).unwrap(),
|
||||
Selector::ArrayIndex(0).eval(&json_books()).unwrap(),
|
||||
JsonpathResult::SingleEntry(json_first_book())
|
||||
);
|
||||
assert_eq!(
|
||||
Selector::ArrayIndex(vec![1, 2])
|
||||
Selector::ArrayIndices(vec![1, 2])
|
||||
.eval(&json_books())
|
||||
.unwrap(),
|
||||
JsonpathResult::Collection(vec![json_second_book(), json_third_book()])
|
||||
@ -458,9 +453,13 @@ mod tests {
|
||||
pub fn test_array_index() {
|
||||
let value = json!(["first", "second", "third", "forth", "fifth"]);
|
||||
assert_eq!(
|
||||
Selector::ArrayIndex(vec![2]).eval(&value).unwrap(),
|
||||
Selector::ArrayIndex(2).eval(&value).unwrap(),
|
||||
JsonpathResult::SingleEntry(json!("third"))
|
||||
);
|
||||
assert_eq!(
|
||||
Selector::ArrayIndices(vec![2, 3]).eval(&value).unwrap(),
|
||||
JsonpathResult::Collection(vec![json!("third"), json!("forth")])
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -50,7 +50,7 @@ fn selector(reader: &mut Reader) -> ParseResult<Selector> {
|
||||
selector_wildcard,
|
||||
selector_recursive_wildcard,
|
||||
selector_recursive_key,
|
||||
selector_array_index,
|
||||
selector_array_index_or_array_indices,
|
||||
selector_array_wildcard,
|
||||
selector_array_slice,
|
||||
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)?;
|
||||
let mut indexes = vec![];
|
||||
let i = match natural(reader) {
|
||||
@ -94,7 +94,12 @@ fn selector_array_index(reader: &mut Reader) -> Result<Selector, Error> {
|
||||
}
|
||||
}
|
||||
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> {
|
||||
@ -312,7 +317,7 @@ mod tests {
|
||||
#[test]
|
||||
pub fn test_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);
|
||||
|
||||
@ -338,7 +343,7 @@ mod tests {
|
||||
selectors: vec![
|
||||
Selector::NameChild("store".to_string()),
|
||||
Selector::NameChild("book".to_string()),
|
||||
Selector::ArrayIndex(vec![0]),
|
||||
Selector::ArrayIndex(0),
|
||||
Selector::NameChild("title".to_string()),
|
||||
],
|
||||
};
|
||||
@ -354,7 +359,7 @@ mod tests {
|
||||
let expected_query = Query {
|
||||
selectors: vec![
|
||||
Selector::RecursiveKey("book".to_string()),
|
||||
Selector::ArrayIndex(vec![2]),
|
||||
Selector::ArrayIndex(2),
|
||||
],
|
||||
};
|
||||
assert_eq!(
|
||||
@ -423,26 +428,20 @@ mod tests {
|
||||
#[test]
|
||||
pub fn test_selector_array_index() {
|
||||
let mut reader = Reader::new("[2]");
|
||||
assert_eq!(
|
||||
selector(&mut reader).unwrap(),
|
||||
Selector::ArrayIndex(vec![2])
|
||||
);
|
||||
assert_eq!(selector(&mut reader).unwrap(), Selector::ArrayIndex(2));
|
||||
assert_eq!(reader.state.cursor, 3);
|
||||
|
||||
let mut reader = Reader::new("[0,1]");
|
||||
assert_eq!(
|
||||
selector(&mut reader).unwrap(),
|
||||
Selector::ArrayIndex(vec![0, 1])
|
||||
Selector::ArrayIndices(vec![0, 1])
|
||||
);
|
||||
assert_eq!(reader.state.cursor, 5);
|
||||
|
||||
// you don't need to keep the exact string
|
||||
// this is not part of the AST
|
||||
let mut reader = Reader::new(".[2]");
|
||||
assert_eq!(
|
||||
selector(&mut reader).unwrap(),
|
||||
Selector::ArrayIndex(vec![2])
|
||||
);
|
||||
assert_eq!(selector(&mut reader).unwrap(), Selector::ArrayIndex(2));
|
||||
assert_eq!(reader.state.cursor, 4);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user