From dcf82e88ff3baa75cfed8e0ec1335871bb456e80 Mon Sep 17 00:00:00 2001 From: Wojciech Kozlowski Date: Fri, 14 Apr 2023 00:17:30 +0200 Subject: [PATCH] Use sets for queries --- src/library/beets.rs | 60 ++++++++++++++++++++++++++------------------ src/library/mod.rs | 20 ++++++++------- 2 files changed, 46 insertions(+), 34 deletions(-) diff --git a/src/library/beets.rs b/src/library/beets.rs index 9bd9acb..ee6bf88 100644 --- a/src/library/beets.rs +++ b/src/library/beets.rs @@ -296,39 +296,45 @@ mod tests { #[test] fn test_query() { + let mut query = Query::new() + .exclude(Field::AlbumTitle(String::from("some.album"))) + .include(Field::TrackNumber(5)) + .include(Field::TrackArtist(vec![ + String::from("some.artist.1"), + String::from("some.artist.2"), + ])) + .exclude(Field::All(String::from("some.all"))) + .to_args(); + query.sort(); + assert_eq!( - Query::new() - .exclude(Field::AlbumTitle(String::from("some.album"))) - .include(Field::TrackNumber(5)) - .include(Field::TrackArtist(vec![ - String::from("some.artist.1"), - String::from("some.artist.2"), - ])) - .exclude(Field::All(String::from("some.all"))) - .to_args(), + 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"), ] ); + let mut query = Query::default() + .exclude(Field::AlbumArtist(String::from("some.albumartist"))) + .include(Field::AlbumYear(3030)) + .include(Field::TrackTitle(String::from("some.track"))) + .exclude(Field::TrackArtist(vec![ + String::from("some.artist.1"), + String::from("some.artist.2"), + ])) + .to_args(); + query.sort(); + assert_eq!( - Query::default() - .exclude(Field::AlbumArtist(String::from("some.albumartist"))) - .include(Field::AlbumYear(3030)) - .include(Field::TrackTitle(String::from("some.track"))) - .exclude(Field::TrackArtist(vec![ - String::from("some.artist.1"), - String::from("some.artist.2"), - ])) - .to_args(), + 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); diff --git a/src/library/mod.rs b/src/library/mod.rs index 381f273..855c637 100644 --- a/src/library/mod.rs +++ b/src/library/mod.rs @@ -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, - exclude: Vec, + include: HashSet, + exclude: HashSet, } 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"))), ) }