use hurl_core::reader::Reader;
use crate::jsonpath::ast::query::{AbsoluteQuery, Query, RelativeQuery};
use crate::jsonpath::parser::primitives::{expect_str, match_str};
use crate::jsonpath::parser::{ParseError, ParseErrorKind, ParseResult, segments};
pub fn parse(reader: &mut Reader) -> ParseResult<AbsoluteQuery> {
expect_str("$", reader)?;
let segments = segments::parse(reader)?;
if reader.is_eof() {
Ok(AbsoluteQuery::new(segments))
} else {
Err(ParseError::new(
reader.cursor().pos,
ParseErrorKind::Expecting("end of query".to_string()),
))
}
}
pub fn try_filter_query(reader: &mut Reader) -> ParseResult<Option<Query>> {
if let Some(relative_query) = try_relative_query(reader)? {
Ok(Some(Query::RelativeQuery(relative_query)))
} else if let Some(absolute_query) = try_absolute_query(reader)? {
Ok(Some(Query::AbsoluteQuery(absolute_query)))
} else {
Ok(None)
}
}
pub fn try_relative_query(reader: &mut Reader) -> ParseResult<Option<RelativeQuery>> {
if match_str("@", reader) {
let segments = segments::parse(reader)?;
Ok(Some(RelativeQuery::new(segments)))
} else {
Ok(None)
}
}
pub fn try_absolute_query(reader: &mut Reader) -> ParseResult<Option<AbsoluteQuery>> {
if match_str("$", reader) {
let segments = segments::parse(reader)?;
Ok(Some(AbsoluteQuery::new(segments)))
} else {
Ok(None)
}
}
#[cfg(test)]
mod tests {
use super::super::{ParseError, ParseErrorKind};
use crate::jsonpath::ast::expr::{LogicalExpr, TestExpr, TestExprKind};
use crate::jsonpath::ast::query::{Query, RelativeQuery};
use crate::jsonpath::ast::segment::{ChildSegment, Segment};
use crate::jsonpath::ast::selector::{FilterSelector, NameSelector, Selector};
use hurl_core::reader::{CharPos, Pos, Reader};
use super::*;
#[test]
pub fn test_empty() {
let mut reader = Reader::new("");
assert_eq!(
parse(&mut reader).unwrap_err(),
ParseError::new(Pos::new(1, 1), ParseErrorKind::Expecting("$".to_string()))
);
assert_eq!(reader.cursor().index, CharPos(0));
}
#[test]
pub fn test_trailing_space() {
let mut reader = Reader::new("$ ");
assert_eq!(
parse(&mut reader).unwrap_err(),
ParseError::new(
Pos::new(1, 2),
ParseErrorKind::Expecting("end of query".to_string())
)
);
assert_eq!(reader.cursor().index, CharPos(1));
}
#[test]
pub fn test_root_identifier() {
let mut reader = Reader::new("$");
assert_eq!(parse(&mut reader).unwrap(), AbsoluteQuery::new(vec![]));
assert_eq!(reader.cursor().index, CharPos(1));
}
#[test]
pub fn test_child_segment() {
let mut reader = Reader::new("$['store']");
assert_eq!(
parse(&mut reader).unwrap(),
AbsoluteQuery::new(vec![Segment::Child(ChildSegment::new(vec![
Selector::Name(NameSelector::new("store".to_string()))
]))])
);
assert_eq!(reader.cursor().index, CharPos(10));
let mut reader = Reader::new("$[?@['isbn']]");
assert_eq!(
parse(&mut reader).unwrap(),
AbsoluteQuery::new(vec![Segment::Child(ChildSegment::new(vec![
Selector::Filter(FilterSelector::new(LogicalExpr::Test(TestExpr::new(
false,
TestExprKind::FilterQuery(Query::RelativeQuery(RelativeQuery::new(vec![
Segment::Child(ChildSegment::new(vec![Selector::Name(NameSelector::new(
"isbn".to_string()
))]))
])))
))))
]))])
);
assert_eq!(reader.cursor().index, CharPos(13));
let mut reader = Reader::new("$.book");
assert_eq!(
parse(&mut reader).unwrap(),
AbsoluteQuery::new(vec![Segment::Child(ChildSegment::new(vec![
Selector::Name(NameSelector::new("book".to_string()))
]))])
);
assert_eq!(reader.cursor().index, CharPos(6));
}
#[test]
pub fn test_relative_query() {
let mut reader = Reader::new("@['isbn']");
assert_eq!(
try_relative_query(&mut reader).unwrap().unwrap(),
RelativeQuery::new(vec![Segment::Child(ChildSegment::new(vec![
Selector::Name(NameSelector::new("isbn".to_string()))
]))])
);
assert_eq!(reader.cursor().index, CharPos(9));
}
}