diff --git a/filter-parser/src/lib.rs b/filter-parser/src/lib.rs index bfb02d63c..4b78b86b8 100644 --- a/filter-parser/src/lib.rs +++ b/filter-parser/src/lib.rs @@ -192,6 +192,19 @@ fn parse_in(input: Span) -> IResult { let filter = FilterCondition::In { fid: value, els: content }; Ok((input, filter)) } +/// in = value "NOT" WS* "IN" "[" value_list "]" +fn parse_not_in(input: Span) -> IResult { + let (input, value) = parse_value(input)?; + let (input, _) = tag("NOT")(input)?; + let (input, _) = multispace1(input)?; + let (input, _) = ws(tag("IN"))(input)?; + + let mut els_parser = delimited(tag("["), parse_value_list, tag("]")); + + let (input, content) = els_parser(input)?; + let filter = FilterCondition::Not(Box::new(FilterCondition::In { fid: value, els: content })); + Ok((input, filter)) +} /// or = and ("OR" and) fn parse_or(input: Span) -> IResult { @@ -290,6 +303,7 @@ fn parse_primary(input: Span) -> IResult { ), parse_geo_radius, parse_in, + parse_not_in, parse_condition, parse_exists, parse_not_exists, @@ -361,6 +375,16 @@ pub mod tests { ] } ), + ( + "colour NOT IN[green,blue]", + Fc::Not(Box::new(Fc::In { + fid: rtok("", "colour"), + els: vec![ + rtok("colour NOT IN[", "green"), + rtok("colour NOT IN[green, ", "blue"), + ] + })) + ), ( " colour IN [ green , blue , ]", Fc::In {