Adds NOT search operator
This commit is contained in:
parent
f971b78856
commit
b943d9aa11
2 changed files with 31 additions and 1 deletions
|
@ -54,6 +54,7 @@ pub enum Literal {
|
||||||
pub enum BoolOp {
|
pub enum BoolOp {
|
||||||
And,
|
And,
|
||||||
Or,
|
Or,
|
||||||
|
Not,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
|
@ -128,7 +129,12 @@ pub fn make_parser() -> impl Parser<char, Expr, Error = Simple<char>> {
|
||||||
let filter = choice((text_cmp, number_cmp, fuzzy));
|
let filter = choice((text_cmp, number_cmp, fuzzy));
|
||||||
let atom = choice((filter, expr.delimited_by(just('('), just(')'))));
|
let atom = choice((filter, expr.delimited_by(just('('), just(')'))));
|
||||||
|
|
||||||
let bool_op = choice((just("&&").to(BoolOp::And), just("||").to(BoolOp::Or))).padded();
|
let bool_op = choice((
|
||||||
|
just("&&").to(BoolOp::And),
|
||||||
|
just("||").to(BoolOp::Or),
|
||||||
|
just("!!").to(BoolOp::Not),
|
||||||
|
))
|
||||||
|
.padded();
|
||||||
|
|
||||||
let combined = atom
|
let combined = atom
|
||||||
.clone()
|
.clone()
|
||||||
|
|
|
@ -119,6 +119,8 @@ impl Search {
|
||||||
match (left, op, right) {
|
match (left, op, right) {
|
||||||
(Some(l), BoolOp::And, Some(r)) => l.intersection(&r).cloned().collect(),
|
(Some(l), BoolOp::And, Some(r)) => l.intersection(&r).cloned().collect(),
|
||||||
(Some(l), BoolOp::Or, Some(r)) => l.union(&r).cloned().collect(),
|
(Some(l), BoolOp::Or, Some(r)) => l.union(&r).cloned().collect(),
|
||||||
|
(Some(l), BoolOp::Not, Some(r)) => l.difference(&r).cloned().collect(),
|
||||||
|
(None, BoolOp::Not, _) => IntSet::default(),
|
||||||
(Some(l), _, None) => l,
|
(Some(l), _, None) => l,
|
||||||
(None, _, Some(r)) => r,
|
(None, _, Some(r)) => r,
|
||||||
(None, _, None) => IntSet::default(),
|
(None, _, None) => IntSet::default(),
|
||||||
|
@ -605,6 +607,28 @@ mod test {
|
||||||
assert!(songs.contains(&PathBuf::from("whales in space.mp3")));
|
assert!(songs.contains(&PathBuf::from("whales in space.mp3")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn can_use_not_operator() {
|
||||||
|
let ctx = setup_test(vec![
|
||||||
|
scanner::Song {
|
||||||
|
virtual_path: PathBuf::from("whale.mp3"),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
scanner::Song {
|
||||||
|
virtual_path: PathBuf::from("space.mp3"),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
scanner::Song {
|
||||||
|
virtual_path: PathBuf::from("whales in space.mp3"),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
let songs = ctx.search("whale !! space");
|
||||||
|
assert_eq!(songs.len(), 1);
|
||||||
|
assert!(songs.contains(&PathBuf::from("whale.mp3")));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn results_are_sorted() {
|
fn results_are_sorted() {
|
||||||
let ctx = setup_test(vec![
|
let ctx = setup_test(vec![
|
||||||
|
|
Loading…
Add table
Reference in a new issue