use super::argument;
use crate::jsonpath::ast::function::functions::{LogicalTypeFunction, ValueTypeFunction};
use crate::jsonpath::parser::ParseResult;
use crate::jsonpath::parser::primitives::{expect_str, match_str, skip_whitespace};
use hurl_core::reader::Reader;
pub fn try_value_type_function(reader: &mut Reader) -> ParseResult<Option<ValueTypeFunction>> {
if match_str("length", reader) {
expect_str("(", reader)?;
skip_whitespace(reader);
let argument = argument::value_type(reader)?;
skip_whitespace(reader);
expect_str(")", reader)?;
Ok(Some(ValueTypeFunction::Length(argument)))
} else if match_str("value", reader) {
expect_str("(", reader)?;
skip_whitespace(reader);
let argument = argument::nodes_type(reader)?;
skip_whitespace(reader);
expect_str(")", reader)?;
Ok(Some(ValueTypeFunction::Value(argument)))
} else if match_str("count", reader) {
expect_str("(", reader)?;
skip_whitespace(reader);
let argument = argument::nodes_type(reader)?;
skip_whitespace(reader);
expect_str(")", reader)?;
Ok(Some(ValueTypeFunction::Count(argument)))
} else {
Ok(None)
}
}
pub fn try_logical_type_function(reader: &mut Reader) -> ParseResult<Option<LogicalTypeFunction>> {
if match_str("match", reader) {
expect_str("(", reader)?;
skip_whitespace(reader);
let argument1 = argument::value_type(reader)?;
skip_whitespace(reader);
expect_str(",", reader)?;
skip_whitespace(reader);
let argument2 = argument::regex_value_type(reader)?;
skip_whitespace(reader);
expect_str(")", reader)?;
Ok(Some(LogicalTypeFunction::Match(argument1, argument2)))
} else if match_str("search", reader) {
expect_str("(", reader)?;
skip_whitespace(reader);
let argument1 = argument::value_type(reader)?;
skip_whitespace(reader);
expect_str(",", reader)?;
skip_whitespace(reader);
let argument2 = argument::regex_value_type(reader)?;
skip_whitespace(reader);
expect_str(")", reader)?;
Ok(Some(LogicalTypeFunction::Search(argument1, argument2)))
} else {
Ok(None)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::jsonpath::ast::function::argument::{
NodesTypeArgument, RegexValueTypeArgument, ValueTypeArgument,
};
use crate::jsonpath::ast::literal::Literal;
use crate::jsonpath::ast::query::{AbsoluteQuery, Query, RelativeQuery};
use crate::jsonpath::ast::segment::{ChildSegment, DescendantSegment, Segment};
use crate::jsonpath::ast::selector::{NameSelector, Selector, WildcardSelector};
use crate::jsonpath::ast::singular_query::{
RelativeSingularQuery, SingularQuery, SingularQuerySegment,
};
use crate::jsonpath::parser::{ParseError, ParseErrorKind};
use hurl_core::reader::{CharPos, Pos};
use regex::Regex;
#[test]
pub fn test_length_function() {
let mut reader = Reader::new("length(\"abc\")");
assert_eq!(
try_value_type_function(&mut reader).unwrap().unwrap(),
ValueTypeFunction::Length(ValueTypeArgument::Literal(Literal::String(
"abc".to_string()
)))
);
assert_eq!(reader.cursor().index, CharPos(13));
let mut reader = Reader::new("length(value($..c))");
assert_eq!(
try_value_type_function(&mut reader).unwrap().unwrap(),
ValueTypeFunction::Length(ValueTypeArgument::Function(Box::new(
ValueTypeFunction::Value(NodesTypeArgument::FilterQuery(Query::AbsoluteQuery(
AbsoluteQuery::new(vec![Segment::Descendant(DescendantSegment::new(vec![
Selector::Name(NameSelector::new("c".to_string()))
]))])
)))
)))
);
assert_eq!(reader.cursor().index, CharPos(19));
}
#[test]
pub fn test_length_function_error() {
let mut reader = Reader::new("length(@.*)");
assert_eq!(
try_value_type_function(&mut reader).unwrap_err(),
ParseError::new(Pos::new(1, 9), ParseErrorKind::Expecting(")".to_string()))
);
}
#[test]
pub fn test_count_function() {
let mut reader = Reader::new("count(@.*.author)");
assert_eq!(
try_value_type_function(&mut reader).unwrap().unwrap(),
ValueTypeFunction::Count(NodesTypeArgument::FilterQuery(Query::RelativeQuery(
RelativeQuery::new(vec![
Segment::Child(ChildSegment::new(vec![Selector::Wildcard(
WildcardSelector
)])),
Segment::Child(ChildSegment::new(vec![Selector::Name(NameSelector::new(
"author".to_string()
)),]))
])
)))
);
assert_eq!(reader.cursor().index, CharPos(17));
}
#[test]
pub fn test_count_function_error() {
let mut reader = Reader::new("count(1)");
assert_eq!(
try_value_type_function(&mut reader).unwrap_err(),
ParseError::new(
Pos::new(1, 7),
ParseErrorKind::Expecting("a NodesType argument".to_string())
)
);
}
#[test]
pub fn test_match_function() {
let mut reader = Reader::new("match(@.date, \"1974-05-01\")");
assert_eq!(
try_logical_type_function(&mut reader).unwrap().unwrap(),
LogicalTypeFunction::Match(
ValueTypeArgument::SingularQuery(SingularQuery::Relative(
RelativeSingularQuery::new(vec![SingularQuerySegment::Name(
NameSelector::new("date".to_string())
)])
)),
RegexValueTypeArgument::Literal(Regex::new("1974-05-01").unwrap())
)
);
assert_eq!(reader.cursor().index, CharPos(27));
}
#[test]
pub fn test_search_function() {
let mut reader = Reader::new("search(@.author, \"[BR]ob\")");
assert_eq!(
try_logical_type_function(&mut reader).unwrap().unwrap(),
LogicalTypeFunction::Search(
ValueTypeArgument::SingularQuery(SingularQuery::Relative(
RelativeSingularQuery::new(vec![SingularQuerySegment::Name(
NameSelector::new("author".to_string())
)])
)),
RegexValueTypeArgument::Literal(Regex::new("[BR]ob").unwrap())
)
);
assert_eq!(reader.cursor().index, CharPos(26));
}
#[test]
pub fn test_value_function() {
let mut reader = Reader::new("value(@..color)");
assert_eq!(
try_value_type_function(&mut reader).unwrap().unwrap(),
ValueTypeFunction::Value(NodesTypeArgument::FilterQuery(Query::RelativeQuery(
RelativeQuery::new(vec![Segment::Descendant(DescendantSegment::new(vec![
Selector::Name(NameSelector::new("color".to_string()))
]))])
)))
);
assert_eq!(reader.cursor().index, CharPos(15));
}
}