diff --git a/filter_parser/src/condition.rs b/filter_parser/src/condition.rs index c7a9a85a0..faacceb72 100644 --- a/filter_parser/src/condition.rs +++ b/filter_parser/src/condition.rs @@ -9,10 +9,9 @@ use nom::branch::alt; use nom::bytes::complete::tag; use nom::combinator::cut; use nom::sequence::tuple; -use nom::IResult; use Condition::*; -use crate::{parse_value, FPError, FilterCondition, Span, Token}; +use crate::{parse_value, FilterCondition, IResult, Span, Token}; #[derive(Debug, Clone, PartialEq, Eq)] pub enum Condition<'a> { @@ -42,9 +41,7 @@ impl<'a> Condition<'a> { } /// condition = value ("==" | ">" ...) value -pub fn parse_condition<'a, E: FPError<'a>>( - input: Span<'a>, -) -> IResult, FilterCondition, E> { +pub fn parse_condition(input: Span) -> IResult { let operator = alt((tag("<="), tag(">="), tag("!="), tag("<"), tag(">"), tag("="))); let (input, (key, op, value)) = tuple((|c| parse_value(c), operator, cut(parse_value)))(input)?; @@ -74,7 +71,7 @@ pub fn parse_condition<'a, E: FPError<'a>>( } /// to = value value TO value -pub fn parse_to<'a, E: FPError<'a>>(input: Span<'a>) -> IResult { +pub fn parse_to(input: Span) -> IResult { let (input, (key, from, _, to)) = tuple((|c| parse_value(c), |c| parse_value(c), tag("TO"), cut(parse_value)))(input)?; diff --git a/filter_parser/src/lib.rs b/filter_parser/src/lib.rs index 5b8107b82..86c6cd79c 100644 --- a/filter_parser/src/lib.rs +++ b/filter_parser/src/lib.rs @@ -37,16 +37,13 @@ use nom::error::{ContextError, ParseError}; use nom::multi::{many0, separated_list1}; use nom::number::complete::recognize_float; use nom::sequence::{delimited, preceded, terminated, tuple}; -use nom::{Finish, IResult}; +use nom::Finish; use nom_locate::LocatedSpan; pub(crate) use value::parse_value; pub type Span<'a> = LocatedSpan<&'a str, &'a str>; -pub trait FilterParserError<'a>: ParseError> + ContextError> {} -impl<'a, T> FilterParserError<'a> for T where T: ParseError> + ContextError> {} - -use FilterParserError as FPError; +type IResult<'a, Ret> = nom::IResult, Ret, Error<'a>>; #[derive(Debug, Clone, PartialEq, Eq)] pub struct Token<'a> { @@ -96,24 +93,22 @@ impl<'a> FilterCondition<'a> { } } - pub fn parse>(input: &'a str) -> Result { + pub fn parse(input: &'a str) -> Result { if input.trim().is_empty() { return Ok(Self::Empty); } let span = Span::new_extra(input, input); - parse_filter::<'a, E>(span).finish().map(|(_rem, output)| output) + parse_filter(span).finish().map(|(_rem, output)| output) } } // remove OPTIONAL whitespaces before AND after the the provided parser -fn ws<'a, O, E: FPError<'a>>( - inner: impl FnMut(Span<'a>) -> IResult, -) -> impl FnMut(Span<'a>) -> IResult { +fn ws<'a, O>(inner: impl FnMut(Span<'a>) -> IResult) -> impl FnMut(Span<'a>) -> IResult { delimited(multispace0, inner, multispace0) } /// and = not (~ "AND" not)* -fn parse_or<'a, E: FPError<'a>>(input: Span<'a>) -> IResult { +fn parse_or(input: Span) -> IResult { let (input, lhs) = parse_and(input)?; let (input, ors) = many0(preceded(ws(tag("OR")), cut(parse_and)))(input)?; @@ -123,7 +118,7 @@ fn parse_or<'a, E: FPError<'a>>(input: Span<'a>) -> IResult>(input: Span<'a>) -> IResult { +fn parse_and(input: Span) -> IResult { let (input, lhs) = parse_not(input)?; let (input, ors) = many0(preceded(ws(tag("AND")), cut(parse_not)))(input)?; let expr = ors @@ -133,7 +128,7 @@ fn parse_and<'a, E: FPError<'a>>(input: Span<'a>) -> IResult>(input: Span<'a>) -> IResult { +fn parse_not(input: Span) -> IResult { alt(( map(preceded(alt((tag("!"), tag("NOT"))), cut(parse_not)), |e| e.negate()), cut(parse_primary), @@ -141,7 +136,7 @@ fn parse_not<'a, E: FPError<'a>>(input: Span<'a>) -> IResult>(input: Span<'a>) -> IResult, FilterCondition, E> { +fn parse_geo_radius(input: Span) -> IResult { let err_msg_args_incomplete = "_geoRadius. The `_geoRadius` filter expect three arguments: `_geoRadius(latitude, longitude, radius)`"; // we want to forbid space BEFORE the _geoRadius but not after @@ -153,8 +148,8 @@ fn parse_geo_radius<'a, E: FPError<'a>>(input: Span<'a>) -> IResult, Fi let (input, args): (Span, Vec) = parsed?; if args.len() != 3 { - let e = E::from_char(input, '('); - return Err(nom::Err::Failure(E::add_context(input, err_msg_args_incomplete, e))); + let e = Error::from_char(input, '('); + return Err(nom::Err::Failure(Error::add_context(input, err_msg_args_incomplete, e))); } let res = FilterCondition::GeoLowerThan { @@ -165,7 +160,7 @@ fn parse_geo_radius<'a, E: FPError<'a>>(input: Span<'a>) -> IResult, Fi } /// primary = (WS* ~ "(" expression ")" ~ WS*) | geoRadius | condition | to -fn parse_primary<'a, E: FPError<'a>>(input: Span<'a>) -> IResult { +fn parse_primary(input: Span) -> IResult { alt(( delimited(ws(char('(')), cut(parse_expression), cut(ws(char(')')))), |c| parse_geo_radius(c), @@ -175,12 +170,12 @@ fn parse_primary<'a, E: FPError<'a>>(input: Span<'a>) -> IResult>(input: Span<'a>) -> IResult { +pub fn parse_expression(input: Span) -> IResult { parse_or(input) } /// filter = expression ~ EOF -pub fn parse_filter<'a, E: FPError<'a>>(input: Span<'a>) -> IResult { +pub fn parse_filter(input: Span) -> IResult { terminated(parse_expression, eof)(input) } @@ -472,7 +467,7 @@ pub mod tests { ]; for (input, expected) in test_case { - let result = Fc::parse::>(input); + let result = Fc::parse(input); assert!( result.is_ok(), @@ -489,22 +484,22 @@ pub mod tests { fn error() { use FilterCondition as Fc; - let result = Fc::parse::>("test = truc OR truc"); + let result = Fc::parse("test = truc OR truc"); assert!(result.is_err()); let test_case = [ // simple test + ("channel = Ponce = 12", "An error occured"), ("OR", "An error occured"), ("AND", "An error occured"), ("channel = Ponce OR", "An error occured"), - ("channel = Ponce = 12", "An error occured"), ("_geoRadius = 12", "An error occured"), ("_geoPoint(12, 13, 14)", "An error occured"), ("_geo = _geoRadius(12, 13, 14)", "An error occured"), ]; for (input, expected) in test_case { - let result = Fc::parse::>(input); + let result = Fc::parse(input); assert!( result.is_err(), diff --git a/filter_parser/src/value.rs b/filter_parser/src/value.rs index 55c9aec23..7c708aa73 100644 --- a/filter_parser/src/value.rs +++ b/filter_parser/src/value.rs @@ -2,25 +2,25 @@ use nom::branch::alt; use nom::bytes::complete::{take_till, take_while1}; use nom::character::complete::char; use nom::sequence::delimited; -use nom::IResult; -use crate::{ws, FPError, Span, Token}; +use crate::{ws, Error, IResult, Span, Token}; /// value = WS* ~ ( word | singleQuoted | doubleQuoted) ~ WS* -pub fn parse_value<'a, E: FPError<'a>>(input: Span<'a>) -> IResult, Token, E> { +pub fn parse_value(input: Span) -> IResult { // singleQuoted = "'" .* all but quotes "'" - let simple_quoted_key = |input| take_till(|c: char| c == '\'')(input); + let simple_quoted = |input| take_till(|c: char| c == '\'')(input); // doubleQuoted = "\"" (word | spaces)* "\"" - let quoted_key = |input| take_till(|c: char| c == '"')(input); + let double_quoted = |input| take_till(|c: char| c == '"')(input); // word = (alphanumeric | _ | - | .)+ let word = |input| take_while1(is_key_component)(input); - alt(( - ws(delimited(char('\''), simple_quoted_key, char('\''))), - ws(delimited(char('"'), quoted_key, char('"'))), - ws(word), - ))(input) + ws(alt(( + delimited(char('\''), simple_quoted, char('\'')), + delimited(char('"'), double_quoted, char('"')), + word, + )))(input) .map(|(s, t)| (s, t.into())) + .map_err(|e| e.map(|_| Error::expected_value(input))) } fn is_key_component(c: char) -> bool { @@ -29,8 +29,6 @@ fn is_key_component(c: char) -> bool { #[cfg(test)] pub mod tests { - use nom::error::Error; - use super::*; use crate::tests::rtok; @@ -58,7 +56,7 @@ pub mod tests { for (input, expected) in test_case { let input = Span::new_extra(input, input); - let result = parse_value::>(input); + let result = parse_value(input); assert!( result.is_ok(),