Use sets for queries

This commit is contained in:
Wojciech Kozlowski 2023-04-14 00:17:30 +02:00
parent 9192c4bdb4
commit dcf82e88ff
2 changed files with 46 additions and 34 deletions

View File

@ -296,8 +296,7 @@ mod tests {
#[test]
fn test_query() {
assert_eq!(
Query::new()
let mut query = Query::new()
.exclude(Field::AlbumTitle(String::from("some.album")))
.include(Field::TrackNumber(5))
.include(Field::TrackArtist(vec![
@ -305,17 +304,20 @@ mod tests {
String::from("some.artist.2"),
]))
.exclude(Field::All(String::from("some.all")))
.to_args(),
.to_args();
query.sort();
assert_eq!(
query,
vec![
String::from("track:5"),
String::from("artist:some.artist.1; some.artist.2"),
String::from("^album:some.album"),
String::from("^some.all"),
String::from("artist:some.artist.1; some.artist.2"),
String::from("track:5"),
]
);
assert_eq!(
Query::default()
let mut query = Query::default()
.exclude(Field::AlbumArtist(String::from("some.albumartist")))
.include(Field::AlbumYear(3030))
.include(Field::TrackTitle(String::from("some.track")))
@ -323,12 +325,16 @@ mod tests {
String::from("some.artist.1"),
String::from("some.artist.2"),
]))
.to_args(),
.to_args();
query.sort();
assert_eq!(
query,
vec![
String::from("year:3030"),
String::from("title:some.track"),
String::from("^albumartist:some.albumartist"),
String::from("^artist:some.artist.1; some.artist.2"),
String::from("title:some.track"),
String::from("year:3030"),
]
);
}
@ -439,16 +445,20 @@ mod tests {
let arguments = vec![
"ls".to_string(),
LIST_FORMAT_ARG.to_string(),
String::from("track:5"),
String::from("artist:some.artist"),
String::from("^album:some.album"),
String::from("artist:some.artist"),
String::from("track:5"),
];
let result = Ok(vec![]);
let mut executor = MockBeetsLibraryExecutor::new();
executor
.expect_exec()
.with(predicate::eq(arguments))
.with(predicate::function(move |x: &[String]| {
let mut y = x.to_owned();
y[2..].sort();
y == arguments
}))
.times(1)
.return_once(|_| result);

View File

@ -1,6 +1,6 @@
//! Module for interacting with the music library.
use std::{fmt, num::ParseIntError, str::Utf8Error};
use std::{collections::HashSet, fmt, num::ParseIntError, str::Utf8Error};
#[cfg(test)]
use mockall::automock;
@ -10,7 +10,7 @@ use crate::Artist;
pub mod beets;
/// Individual fields that can be queried on.
#[derive(Debug, PartialEq, Eq)]
#[derive(Debug, Hash, PartialEq, Eq)]
pub enum Field {
AlbumArtist(String),
AlbumYear(u32),
@ -24,8 +24,8 @@ pub enum Field {
/// A library query. Can include or exclude particular fields.
#[derive(Debug, PartialEq, Eq)]
pub struct Query {
include: Vec<Field>,
exclude: Vec<Field>,
include: HashSet<Field>,
exclude: HashSet<Field>,
}
impl Default for Query {
@ -39,20 +39,20 @@ impl Query {
/// Create an empty query.
pub fn new() -> Self {
Query {
include: vec![],
exclude: vec![],
include: HashSet::new(),
exclude: HashSet::new(),
}
}
/// Refine the query to include a particular search term.
pub fn include(&mut self, field: Field) -> &mut Self {
self.include.push(field);
self.include.insert(field);
self
}
/// Refine the query to exclude a particular search term.
pub fn exclude(&mut self, field: Field) -> &mut Self {
self.exclude.push(field);
self.exclude.insert(field);
self
}
}
@ -121,11 +121,13 @@ mod tests {
let mut rhs = Query::new();
assert_eq!(
lhs.include(Field::AlbumArtist(String::from("some.artist")))
.exclude(Field::TrackTitle(String::from("some.title")))
.exclude(Field::TrackTitle(String::from("some.title")))
.include(Field::TrackNumber(6)),
rhs.exclude(Field::TrackTitle(String::from("some.title")))
.include(Field::TrackNumber(6))
.include(Field::AlbumArtist(String::from("some.artist")))
.include(Field::TrackNumber(6)),
.include(Field::AlbumArtist(String::from("some.artist"))),
)
}