Use a boolean property instead of Not{Term,Phrase}
- Id
- a7e6a889e30664edf0cf1c75b111c7b75d8d8a76
- Author
- Caio
- Commit time
- 2020-01-03T17:00:56+01:00
Modified tique/src/queryparser/interpreter.rs
// May result in Ok(None) because the tokenizer might give us nothing
fn query_from_token(&self, token: &Token) -> Result<Option<Box<dyn Query>>> {
- match token {
- Token::Term(t) => self.assemble_query(t, false),
+ let (query, negate) = match token {
+ Token::Term(t, neg) => (self.assemble_query(t, false)?, *neg),
+ Token::Phrase(p, neg) => (self.assemble_query(p, true)?, *neg),
+ };
- Token::Phrase(p) => self.assemble_query(p, true),
-
- Token::NotTerm(t) => Ok(self
- .assemble_query(t, false)?
- .map(|inner| Self::negate_query(inner))),
-
- Token::NotPhrase(p) => Ok(self
- .assemble_query(p, true)?
- .map(|inner| Self::negate_query(inner))),
+ if negate {
+ Ok(query.map(|inner| Self::negate_query(inner)))
+ } else {
+ Ok(query)
}
}
Modified tique/src/queryparser/parser.rs
use nom::{
self,
branch::alt,
- bytes::complete::{tag, take_while1},
+ bytes::complete::take_while1,
character::complete::{char as is_char, multispace0},
combinator::map,
multi::many0,
#[derive(Debug, PartialEq)]
pub enum Token<'a> {
- NotPhrase(&'a str),
- NotTerm(&'a str),
- Phrase(&'a str),
- Term(&'a str),
+ Phrase(&'a str, bool),
+ Term(&'a str, bool),
}
fn parse_not_phrase(input: &str) -> IResult<&str, Token> {
- map(
- delimited(tag("-\""), take_while1(|c| c != '"'), is_char('"')),
- Token::NotPhrase,
- )(input)
+ map(preceded(is_char('-'), parse_phrase), |t| match t {
+ Token::Phrase(inner, false) => Token::Phrase(inner, true),
+ _ => unreachable!(),
+ })(input)
}
fn parse_phrase(input: &str) -> IResult<&str, Token> {
map(
delimited(is_char('"'), take_while1(|c| c != '"'), is_char('"')),
- Token::Phrase,
+ |s| Token::Phrase(s, false),
)(input)
}
fn parse_term(input: &str) -> IResult<&str, Token> {
- map(take_while1(is_term_char), Token::Term)(input)
+ map(take_while1(is_term_char), |s| Token::Term(s, false))(input)
}
fn parse_not_term(input: &str) -> IResult<&str, Token> {
- map(preceded(is_char('-'), take_while1(is_term_char)), |r| {
- Token::NotTerm(r)
+ map(preceded(is_char('-'), parse_term), |t| match t {
+ Token::Term(inner, false) => Token::Term(inner, true),
+ _ => unreachable!(),
})(input)
}
#[test]
fn term_extraction() {
- assert_eq!(parse_term("gula"), Ok(("", Term("gula"))));
+ assert_eq!(parse_term("gula"), Ok(("", Term("gula", false))));
}
#[test]
fn not_term_extraction() {
- assert_eq!(parse_not_term("-ads"), Ok(("", NotTerm("ads"))))
+ assert_eq!(parse_not_term("-ads"), Ok(("", Term("ads", true))))
}
#[test]
fn phrase_extraction() {
assert_eq!(
parse_phrase("\"gula recipes\""),
- Ok(("", Phrase("gula recipes")))
+ Ok(("", Phrase("gula recipes", false)))
);
}
fn not_phrase_extraction() {
assert_eq!(
parse_not_phrase("-\"ads and tracking\""),
- Ok(("", NotPhrase("ads and tracking")))
+ Ok(("", Phrase("ads and tracking", true)))
);
}
parse_query(" peanut -\"peanut butter\" -sugar "),
Ok((
"",
- vec![Term("peanut"), NotPhrase("peanut butter"), NotTerm("sugar")]
+ vec![
+ Term("peanut", false),
+ Phrase("peanut butter", true),
+ Term("sugar", true)
+ ]
))
);
}
#[test]
fn garbage_is_extracted_as_term() {
- assert_eq!(parse_query("- \""), Ok(("", vec![Term("-"), Term("\"")])));
+ assert_eq!(
+ parse_query("- \""),
+ Ok(("", vec![Term("-", false), Term("\"", false)]))
+ );
}
}