Provide search functionality through the TUI #134

Merged
wojtek merged 35 commits from 24---provide-search-functionality-through-the-tui into main 2024-02-18 22:12:42 +01:00
8 changed files with 229 additions and 75 deletions
Showing only changes of commit 0b697f5484 - Show all commits

View File

@ -2,7 +2,7 @@ pub static DATABASE_JSON: &str = "{\
\"V20240210\":\ \"V20240210\":\
[\ [\
{\ {\
\"name\":\"album_artist a\",\ \"name\":\"Album_Artist A\",\
\"sort\":null,\ \"sort\":null,\
\"musicbrainz\":\"https://musicbrainz.org/artist/00000000-0000-0000-0000-000000000000\",\ \"musicbrainz\":\"https://musicbrainz.org/artist/00000000-0000-0000-0000-000000000000\",\
\"properties\":{\ \"properties\":{\
@ -11,7 +11,7 @@ pub static DATABASE_JSON: &str = "{\
}\ }\
},\ },\
{\ {\
\"name\":\"album_artist b\",\ \"name\":\"Album_Artist B\",\
\"sort\":null,\ \"sort\":null,\
\"musicbrainz\":\"https://musicbrainz.org/artist/11111111-1111-1111-1111-111111111111\",\ \"musicbrainz\":\"https://musicbrainz.org/artist/11111111-1111-1111-1111-111111111111\",\
\"properties\":{\ \"properties\":{\
@ -24,13 +24,13 @@ pub static DATABASE_JSON: &str = "{\
}\ }\
},\ },\
{\ {\
\"name\":\"album_artist c\",\ \"name\":\"Album_Artist C\",\
\"sort\":null,\ \"sort\":null,\
\"musicbrainz\":\"https://musicbrainz.org/artist/11111111-1111-1111-1111-111111111111\",\ \"musicbrainz\":\"https://musicbrainz.org/artist/11111111-1111-1111-1111-111111111111\",\
\"properties\":{}\ \"properties\":{}\
},\ },\
{\ {\
\"name\":\"album_artist d\",\ \"name\":\"Album_Artist D\",\
\"sort\":null,\ \"sort\":null,\
\"musicbrainz\":null,\ \"musicbrainz\":null,\
\"properties\":{}\ \"properties\":{}\

View File

@ -2,27 +2,27 @@ use once_cell::sync::Lazy;
pub static LIBRARY_BEETS: Lazy<Vec<String>> = Lazy::new(|| -> Vec<String> { pub static LIBRARY_BEETS: Lazy<Vec<String>> = Lazy::new(|| -> Vec<String> {
vec![ vec![
String::from("album_artist a -*^- -*^- 1998 -*^- album_title a.a -*^- 1 -*^- track a.a.1 -*^- artist a.a.1 -*^- FLAC -*^- 992"), String::from("Album_Artist A -*^- -*^- 1998 -*^- album_title a.a -*^- 1 -*^- track a.a.1 -*^- artist a.a.1 -*^- FLAC -*^- 992"),
String::from("album_artist a -*^- -*^- 1998 -*^- album_title a.a -*^- 2 -*^- track a.a.2 -*^- artist a.a.2.1; artist a.a.2.2 -*^- MP3 -*^- 320"), String::from("Album_Artist A -*^- -*^- 1998 -*^- album_title a.a -*^- 2 -*^- track a.a.2 -*^- artist a.a.2.1; artist a.a.2.2 -*^- MP3 -*^- 320"),
String::from("album_artist a -*^- -*^- 1998 -*^- album_title a.a -*^- 3 -*^- track a.a.3 -*^- artist a.a.3 -*^- FLAC -*^- 1061"), String::from("Album_Artist A -*^- -*^- 1998 -*^- album_title a.a -*^- 3 -*^- track a.a.3 -*^- artist a.a.3 -*^- FLAC -*^- 1061"),
String::from("album_artist a -*^- -*^- 1998 -*^- album_title a.a -*^- 4 -*^- track a.a.4 -*^- artist a.a.4 -*^- FLAC -*^- 1042"), String::from("Album_Artist A -*^- -*^- 1998 -*^- album_title a.a -*^- 4 -*^- track a.a.4 -*^- artist a.a.4 -*^- FLAC -*^- 1042"),
String::from("album_artist a -*^- -*^- 2015 -*^- album_title a.b -*^- 1 -*^- track a.b.1 -*^- artist a.b.1 -*^- FLAC -*^- 1004"), String::from("Album_Artist A -*^- -*^- 2015 -*^- album_title a.b -*^- 1 -*^- track a.b.1 -*^- artist a.b.1 -*^- FLAC -*^- 1004"),
String::from("album_artist a -*^- -*^- 2015 -*^- album_title a.b -*^- 2 -*^- track a.b.2 -*^- artist a.b.2 -*^- FLAC -*^- 1077"), String::from("Album_Artist A -*^- -*^- 2015 -*^- album_title a.b -*^- 2 -*^- track a.b.2 -*^- artist a.b.2 -*^- FLAC -*^- 1077"),
String::from("album_artist b -*^- -*^- 2003 -*^- album_title b.a -*^- 1 -*^- track b.a.1 -*^- artist b.a.1 -*^- MP3 -*^- 190"), String::from("Album_Artist B -*^- -*^- 2003 -*^- album_title b.a -*^- 1 -*^- track b.a.1 -*^- artist b.a.1 -*^- MP3 -*^- 190"),
String::from("album_artist b -*^- -*^- 2003 -*^- album_title b.a -*^- 2 -*^- track b.a.2 -*^- artist b.a.2.1; artist b.a.2.2 -*^- MP3 -*^- 120"), String::from("Album_Artist B -*^- -*^- 2003 -*^- album_title b.a -*^- 2 -*^- track b.a.2 -*^- artist b.a.2.1; artist b.a.2.2 -*^- MP3 -*^- 120"),
String::from("album_artist b -*^- -*^- 2008 -*^- album_title b.b -*^- 1 -*^- track b.b.1 -*^- artist b.b.1 -*^- FLAC -*^- 1077"), String::from("Album_Artist B -*^- -*^- 2008 -*^- album_title b.b -*^- 1 -*^- track b.b.1 -*^- artist b.b.1 -*^- FLAC -*^- 1077"),
String::from("album_artist b -*^- -*^- 2008 -*^- album_title b.b -*^- 2 -*^- track b.b.2 -*^- artist b.b.2.1; artist b.b.2.2 -*^- MP3 -*^- 320"), String::from("Album_Artist B -*^- -*^- 2008 -*^- album_title b.b -*^- 2 -*^- track b.b.2 -*^- artist b.b.2.1; artist b.b.2.2 -*^- MP3 -*^- 320"),
String::from("album_artist b -*^- -*^- 2009 -*^- album_title b.c -*^- 1 -*^- track b.c.1 -*^- artist b.c.1 -*^- MP3 -*^- 190"), String::from("Album_Artist B -*^- -*^- 2009 -*^- album_title b.c -*^- 1 -*^- track b.c.1 -*^- artist b.c.1 -*^- MP3 -*^- 190"),
String::from("album_artist b -*^- -*^- 2009 -*^- album_title b.c -*^- 2 -*^- track b.c.2 -*^- artist b.c.2.1; artist b.c.2.2 -*^- MP3 -*^- 120"), String::from("Album_Artist B -*^- -*^- 2009 -*^- album_title b.c -*^- 2 -*^- track b.c.2 -*^- artist b.c.2.1; artist b.c.2.2 -*^- MP3 -*^- 120"),
String::from("album_artist b -*^- -*^- 2015 -*^- album_title b.d -*^- 1 -*^- track b.d.1 -*^- artist b.d.1 -*^- MP3 -*^- 190"), String::from("Album_Artist B -*^- -*^- 2015 -*^- album_title b.d -*^- 1 -*^- track b.d.1 -*^- artist b.d.1 -*^- MP3 -*^- 190"),
String::from("album_artist b -*^- -*^- 2015 -*^- album_title b.d -*^- 2 -*^- track b.d.2 -*^- artist b.d.2.1; artist b.d.2.2 -*^- MP3 -*^- 120"), String::from("Album_Artist B -*^- -*^- 2015 -*^- album_title b.d -*^- 2 -*^- track b.d.2 -*^- artist b.d.2.1; artist b.d.2.2 -*^- MP3 -*^- 120"),
String::from("album_artist c -*^- -*^- 1985 -*^- album_title c.a -*^- 1 -*^- track c.a.1 -*^- artist c.a.1 -*^- MP3 -*^- 320"), String::from("Album_Artist C -*^- -*^- 1985 -*^- album_title c.a -*^- 1 -*^- track c.a.1 -*^- artist c.a.1 -*^- MP3 -*^- 320"),
String::from("album_artist c -*^- -*^- 1985 -*^- album_title c.a -*^- 2 -*^- track c.a.2 -*^- artist c.a.2.1; artist c.a.2.2 -*^- MP3 -*^- 120"), String::from("Album_Artist C -*^- -*^- 1985 -*^- album_title c.a -*^- 2 -*^- track c.a.2 -*^- artist c.a.2.1; artist c.a.2.2 -*^- MP3 -*^- 120"),
String::from("album_artist c -*^- -*^- 2018 -*^- album_title c.b -*^- 1 -*^- track c.b.1 -*^- artist c.b.1 -*^- FLAC -*^- 1041"), String::from("Album_Artist C -*^- -*^- 2018 -*^- album_title c.b -*^- 1 -*^- track c.b.1 -*^- artist c.b.1 -*^- FLAC -*^- 1041"),
String::from("album_artist c -*^- -*^- 2018 -*^- album_title c.b -*^- 2 -*^- track c.b.2 -*^- artist c.b.2.1; artist c.b.2.2 -*^- FLAC -*^- 756"), String::from("Album_Artist C -*^- -*^- 2018 -*^- album_title c.b -*^- 2 -*^- track c.b.2 -*^- artist c.b.2.1; artist c.b.2.2 -*^- FLAC -*^- 756"),
String::from("album_artist d -*^- -*^- 1995 -*^- album_title d.a -*^- 1 -*^- track d.a.1 -*^- artist d.a.1 -*^- MP3 -*^- 120"), String::from("Album_Artist D -*^- -*^- 1995 -*^- album_title d.a -*^- 1 -*^- track d.a.1 -*^- artist d.a.1 -*^- MP3 -*^- 120"),
String::from("album_artist d -*^- -*^- 1995 -*^- album_title d.a -*^- 2 -*^- track d.a.2 -*^- artist d.a.2.1; artist d.a.2.2 -*^- MP3 -*^- 120"), String::from("Album_Artist D -*^- -*^- 1995 -*^- album_title d.a -*^- 2 -*^- track d.a.2 -*^- artist d.a.2.1; artist d.a.2.2 -*^- MP3 -*^- 120"),
String::from("album_artist d -*^- -*^- 2028 -*^- album_title d.b -*^- 1 -*^- track d.b.1 -*^- artist d.b.1 -*^- FLAC -*^- 841"), String::from("Album_Artist D -*^- -*^- 2028 -*^- album_title d.b -*^- 1 -*^- track d.b.1 -*^- artist d.b.1 -*^- FLAC -*^- 841"),
String::from("album_artist d -*^- -*^- 2028 -*^- album_title d.b -*^- 2 -*^- track d.b.2 -*^- artist d.b.2.1; artist d.b.2.2 -*^- FLAC -*^- 756") String::from("Album_Artist D -*^- -*^- 2028 -*^- album_title d.b -*^- 2 -*^- track d.b.2 -*^- artist d.b.2.1; artist d.b.2.2 -*^- FLAC -*^- 756")
] ]
}); });

View File

@ -5,7 +5,7 @@ use crate::core::{collection::track::Format, library::Item};
pub static LIBRARY_ITEMS: Lazy<Vec<Item>> = Lazy::new(|| -> Vec<Item> { pub static LIBRARY_ITEMS: Lazy<Vec<Item>> = Lazy::new(|| -> Vec<Item> {
vec![ vec![
Item { Item {
album_artist: String::from("album_artist a"), album_artist: String::from("Album_Artist A"),
album_artist_sort: None, album_artist_sort: None,
album_year: 1998, album_year: 1998,
album_title: String::from("album_title a.a"), album_title: String::from("album_title a.a"),
@ -16,7 +16,7 @@ pub static LIBRARY_ITEMS: Lazy<Vec<Item>> = Lazy::new(|| -> Vec<Item> {
track_bitrate: 992, track_bitrate: 992,
}, },
Item { Item {
album_artist: String::from("album_artist a"), album_artist: String::from("Album_Artist A"),
album_artist_sort: None, album_artist_sort: None,
album_year: 1998, album_year: 1998,
album_title: String::from("album_title a.a"), album_title: String::from("album_title a.a"),
@ -30,7 +30,7 @@ pub static LIBRARY_ITEMS: Lazy<Vec<Item>> = Lazy::new(|| -> Vec<Item> {
track_bitrate: 320, track_bitrate: 320,
}, },
Item { Item {
album_artist: String::from("album_artist a"), album_artist: String::from("Album_Artist A"),
album_artist_sort: None, album_artist_sort: None,
album_year: 1998, album_year: 1998,
album_title: String::from("album_title a.a"), album_title: String::from("album_title a.a"),
@ -41,7 +41,7 @@ pub static LIBRARY_ITEMS: Lazy<Vec<Item>> = Lazy::new(|| -> Vec<Item> {
track_bitrate: 1061, track_bitrate: 1061,
}, },
Item { Item {
album_artist: String::from("album_artist a"), album_artist: String::from("Album_Artist A"),
album_artist_sort: None, album_artist_sort: None,
album_year: 1998, album_year: 1998,
album_title: String::from("album_title a.a"), album_title: String::from("album_title a.a"),
@ -52,7 +52,7 @@ pub static LIBRARY_ITEMS: Lazy<Vec<Item>> = Lazy::new(|| -> Vec<Item> {
track_bitrate: 1042, track_bitrate: 1042,
}, },
Item { Item {
album_artist: String::from("album_artist a"), album_artist: String::from("Album_Artist A"),
album_artist_sort: None, album_artist_sort: None,
album_year: 2015, album_year: 2015,
album_title: String::from("album_title a.b"), album_title: String::from("album_title a.b"),
@ -63,7 +63,7 @@ pub static LIBRARY_ITEMS: Lazy<Vec<Item>> = Lazy::new(|| -> Vec<Item> {
track_bitrate: 1004, track_bitrate: 1004,
}, },
Item { Item {
album_artist: String::from("album_artist a"), album_artist: String::from("Album_Artist A"),
album_artist_sort: None, album_artist_sort: None,
album_year: 2015, album_year: 2015,
album_title: String::from("album_title a.b"), album_title: String::from("album_title a.b"),
@ -74,7 +74,7 @@ pub static LIBRARY_ITEMS: Lazy<Vec<Item>> = Lazy::new(|| -> Vec<Item> {
track_bitrate: 1077, track_bitrate: 1077,
}, },
Item { Item {
album_artist: String::from("album_artist b"), album_artist: String::from("Album_Artist B"),
album_artist_sort: None, album_artist_sort: None,
album_year: 2003, album_year: 2003,
album_title: String::from("album_title b.a"), album_title: String::from("album_title b.a"),
@ -85,7 +85,7 @@ pub static LIBRARY_ITEMS: Lazy<Vec<Item>> = Lazy::new(|| -> Vec<Item> {
track_bitrate: 190, track_bitrate: 190,
}, },
Item { Item {
album_artist: String::from("album_artist b"), album_artist: String::from("Album_Artist B"),
album_artist_sort: None, album_artist_sort: None,
album_year: 2003, album_year: 2003,
album_title: String::from("album_title b.a"), album_title: String::from("album_title b.a"),
@ -99,7 +99,7 @@ pub static LIBRARY_ITEMS: Lazy<Vec<Item>> = Lazy::new(|| -> Vec<Item> {
track_bitrate: 120, track_bitrate: 120,
}, },
Item { Item {
album_artist: String::from("album_artist b"), album_artist: String::from("Album_Artist B"),
album_artist_sort: None, album_artist_sort: None,
album_year: 2008, album_year: 2008,
album_title: String::from("album_title b.b"), album_title: String::from("album_title b.b"),
@ -110,7 +110,7 @@ pub static LIBRARY_ITEMS: Lazy<Vec<Item>> = Lazy::new(|| -> Vec<Item> {
track_bitrate: 1077, track_bitrate: 1077,
}, },
Item { Item {
album_artist: String::from("album_artist b"), album_artist: String::from("Album_Artist B"),
album_artist_sort: None, album_artist_sort: None,
album_year: 2008, album_year: 2008,
album_title: String::from("album_title b.b"), album_title: String::from("album_title b.b"),
@ -124,7 +124,7 @@ pub static LIBRARY_ITEMS: Lazy<Vec<Item>> = Lazy::new(|| -> Vec<Item> {
track_bitrate: 320, track_bitrate: 320,
}, },
Item { Item {
album_artist: String::from("album_artist b"), album_artist: String::from("Album_Artist B"),
album_artist_sort: None, album_artist_sort: None,
album_year: 2009, album_year: 2009,
album_title: String::from("album_title b.c"), album_title: String::from("album_title b.c"),
@ -135,7 +135,7 @@ pub static LIBRARY_ITEMS: Lazy<Vec<Item>> = Lazy::new(|| -> Vec<Item> {
track_bitrate: 190, track_bitrate: 190,
}, },
Item { Item {
album_artist: String::from("album_artist b"), album_artist: String::from("Album_Artist B"),
album_artist_sort: None, album_artist_sort: None,
album_year: 2009, album_year: 2009,
album_title: String::from("album_title b.c"), album_title: String::from("album_title b.c"),
@ -149,7 +149,7 @@ pub static LIBRARY_ITEMS: Lazy<Vec<Item>> = Lazy::new(|| -> Vec<Item> {
track_bitrate: 120, track_bitrate: 120,
}, },
Item { Item {
album_artist: String::from("album_artist b"), album_artist: String::from("Album_Artist B"),
album_artist_sort: None, album_artist_sort: None,
album_year: 2015, album_year: 2015,
album_title: String::from("album_title b.d"), album_title: String::from("album_title b.d"),
@ -160,7 +160,7 @@ pub static LIBRARY_ITEMS: Lazy<Vec<Item>> = Lazy::new(|| -> Vec<Item> {
track_bitrate: 190, track_bitrate: 190,
}, },
Item { Item {
album_artist: String::from("album_artist b"), album_artist: String::from("Album_Artist B"),
album_artist_sort: None, album_artist_sort: None,
album_year: 2015, album_year: 2015,
album_title: String::from("album_title b.d"), album_title: String::from("album_title b.d"),
@ -174,7 +174,7 @@ pub static LIBRARY_ITEMS: Lazy<Vec<Item>> = Lazy::new(|| -> Vec<Item> {
track_bitrate: 120, track_bitrate: 120,
}, },
Item { Item {
album_artist: String::from("album_artist c"), album_artist: String::from("Album_Artist C"),
album_artist_sort: None, album_artist_sort: None,
album_year: 1985, album_year: 1985,
album_title: String::from("album_title c.a"), album_title: String::from("album_title c.a"),
@ -185,7 +185,7 @@ pub static LIBRARY_ITEMS: Lazy<Vec<Item>> = Lazy::new(|| -> Vec<Item> {
track_bitrate: 320, track_bitrate: 320,
}, },
Item { Item {
album_artist: String::from("album_artist c"), album_artist: String::from("Album_Artist C"),
album_artist_sort: None, album_artist_sort: None,
album_year: 1985, album_year: 1985,
album_title: String::from("album_title c.a"), album_title: String::from("album_title c.a"),
@ -199,7 +199,7 @@ pub static LIBRARY_ITEMS: Lazy<Vec<Item>> = Lazy::new(|| -> Vec<Item> {
track_bitrate: 120, track_bitrate: 120,
}, },
Item { Item {
album_artist: String::from("album_artist c"), album_artist: String::from("Album_Artist C"),
album_artist_sort: None, album_artist_sort: None,
album_year: 2018, album_year: 2018,
album_title: String::from("album_title c.b"), album_title: String::from("album_title c.b"),
@ -210,7 +210,7 @@ pub static LIBRARY_ITEMS: Lazy<Vec<Item>> = Lazy::new(|| -> Vec<Item> {
track_bitrate: 1041, track_bitrate: 1041,
}, },
Item { Item {
album_artist: String::from("album_artist c"), album_artist: String::from("Album_Artist C"),
album_artist_sort: None, album_artist_sort: None,
album_year: 2018, album_year: 2018,
album_title: String::from("album_title c.b"), album_title: String::from("album_title c.b"),
@ -224,7 +224,7 @@ pub static LIBRARY_ITEMS: Lazy<Vec<Item>> = Lazy::new(|| -> Vec<Item> {
track_bitrate: 756, track_bitrate: 756,
}, },
Item { Item {
album_artist: String::from("album_artist d"), album_artist: String::from("Album_Artist D"),
album_artist_sort: None, album_artist_sort: None,
album_year: 1995, album_year: 1995,
album_title: String::from("album_title d.a"), album_title: String::from("album_title d.a"),
@ -235,7 +235,7 @@ pub static LIBRARY_ITEMS: Lazy<Vec<Item>> = Lazy::new(|| -> Vec<Item> {
track_bitrate: 120, track_bitrate: 120,
}, },
Item { Item {
album_artist: String::from("album_artist d"), album_artist: String::from("Album_Artist D"),
album_artist_sort: None, album_artist_sort: None,
album_year: 1995, album_year: 1995,
album_title: String::from("album_title d.a"), album_title: String::from("album_title d.a"),
@ -249,7 +249,7 @@ pub static LIBRARY_ITEMS: Lazy<Vec<Item>> = Lazy::new(|| -> Vec<Item> {
track_bitrate: 120, track_bitrate: 120,
}, },
Item { Item {
album_artist: String::from("album_artist d"), album_artist: String::from("Album_Artist D"),
album_artist_sort: None, album_artist_sort: None,
album_year: 2028, album_year: 2028,
album_title: String::from("album_title d.b"), album_title: String::from("album_title d.b"),
@ -260,7 +260,7 @@ pub static LIBRARY_ITEMS: Lazy<Vec<Item>> = Lazy::new(|| -> Vec<Item> {
track_bitrate: 841, track_bitrate: 841,
}, },
Item { Item {
album_artist: String::from("album_artist d"), album_artist: String::from("Album_Artist D"),
album_artist_sort: None, album_artist_sort: None,
album_year: 2028, album_year: 2028,
album_title: String::from("album_title d.b"), album_title: String::from("album_title d.b"),

View File

@ -668,7 +668,7 @@ mod tests {
let mut right: Vec<Artist> = vec![left.last().unwrap().clone()]; let mut right: Vec<Artist> = vec![left.last().unwrap().clone()];
assert!(right.first().unwrap() > left.first().unwrap()); assert!(right.first().unwrap() > left.first().unwrap());
let artist_sort = Some(ArtistId::new("album_artist 0")); let artist_sort = Some(ArtistId::new("Album_Artist 0"));
right[0].sort = artist_sort.clone(); right[0].sort = artist_sort.clone();
assert!(right.first().unwrap() < left.first().unwrap()); assert!(right.first().unwrap() < left.first().unwrap());

View File

@ -3,7 +3,7 @@ macro_rules! library_collection {
vec![ vec![
Artist { Artist {
id: ArtistId { id: ArtistId {
name: "album_artist a".to_string(), name: "Album_Artist A".to_string(),
}, },
sort: None, sort: None,
musicbrainz: None, musicbrainz: None,
@ -98,7 +98,7 @@ macro_rules! library_collection {
}, },
Artist { Artist {
id: ArtistId { id: ArtistId {
name: "album_artist b".to_string(), name: "Album_Artist B".to_string(),
}, },
sort: None, sort: None,
musicbrainz: None, musicbrainz: None,
@ -240,7 +240,7 @@ macro_rules! library_collection {
}, },
Artist { Artist {
id: ArtistId { id: ArtistId {
name: "album_artist c".to_string(), name: "Album_Artist C".to_string(),
}, },
sort: None, sort: None,
musicbrainz: None, musicbrainz: None,
@ -316,7 +316,7 @@ macro_rules! library_collection {
}, },
Artist { Artist {
id: ArtistId { id: ArtistId {
name: "album_artist d".to_string(), name: "Album_Artist D".to_string(),
}, },
sort: None, sort: None,
musicbrainz: None, musicbrainz: None,
@ -400,7 +400,7 @@ macro_rules! full_collection {
let mut iter = collection.iter_mut(); let mut iter = collection.iter_mut();
let artist_a = iter.next().unwrap(); let artist_a = iter.next().unwrap();
assert_eq!(artist_a.id.name, "album_artist a"); assert_eq!(artist_a.id.name, "Album_Artist A");
artist_a.musicbrainz = Some( artist_a.musicbrainz = Some(
MusicBrainz::new( MusicBrainz::new(
@ -421,7 +421,7 @@ macro_rules! full_collection {
]); ]);
let artist_b = iter.next().unwrap(); let artist_b = iter.next().unwrap();
assert_eq!(artist_b.id.name, "album_artist b"); assert_eq!(artist_b.id.name, "Album_Artist B");
artist_b.musicbrainz = Some( artist_b.musicbrainz = Some(
MusicBrainz::new( MusicBrainz::new(
@ -443,7 +443,7 @@ macro_rules! full_collection {
]); ]);
let artist_c = iter.next().unwrap(); let artist_c = iter.next().unwrap();
assert_eq!(artist_c.id.name, "album_artist c"); assert_eq!(artist_c.id.name, "Album_Artist C");
artist_c.musicbrainz = Some( artist_c.musicbrainz = Some(
MusicBrainz::new( MusicBrainz::new(

View File

@ -33,9 +33,27 @@ impl<BS, IS, RS, SS, ES, CS> AppState<BS, IS, RS, SS, ES, CS> {
matches!(self, AppState::Search(_)) matches!(self, AppState::Search(_))
} }
pub fn unwrap_search(self) -> SS {
match self {
AppState::Search(ss) => ss,
_ => panic!(),
}
}
pub fn is_error(&self) -> bool { pub fn is_error(&self) -> bool {
matches!(self, AppState::Error(_)) matches!(self, AppState::Error(_))
} }
pub fn as_mut(&mut self) -> AppState<&mut BS, &mut IS, &mut RS, &mut SS, &mut ES, &mut CS> {
match self {
AppState::Browse(ref mut bs) => AppState::Browse(bs),
AppState::Info(ref mut is) => AppState::Info(is),
AppState::Reload(ref mut rs) => AppState::Reload(rs),
AppState::Search(ref mut ss) => AppState::Search(ss),
AppState::Error(ref mut es) => AppState::Error(es),
AppState::Critical(ref mut cs) => AppState::Critical(cs),
}
}
} }
pub trait IAppInteract { pub trait IAppInteract {
@ -275,28 +293,20 @@ impl<MH: IMusicHoard> IAppInteractReloadPrivate for App<MH> {
impl<MH: IMusicHoard> IAppInteractSearch for App<MH> { impl<MH: IMusicHoard> IAppInteractSearch for App<MH> {
fn append_character(&mut self, ch: char) { fn append_character(&mut self, ch: char) {
match self.state { let s = self.state.as_mut().unwrap_search();
AppState::Search(ref mut s) => {
s.push(ch); s.push(ch);
self.selection self.selection
.incremental_artist_search(self.music_hoard.get_collection(), s); .incremental_artist_search(self.music_hoard.get_collection(), s);
} }
_ => unreachable!(),
}
}
fn remove_character(&mut self) { fn remove_character(&mut self) {
match self.state { let s = self.state.as_mut().unwrap_search();
AppState::Search(ref mut s) => {
s.pop(); s.pop();
self.selection self.selection
.reset_artist(self.music_hoard.get_collection()); .reset_artist(self.music_hoard.get_collection());
self.selection self.selection
.incremental_artist_search(self.music_hoard.get_collection(), s); .incremental_artist_search(self.music_hoard.get_collection(), s);
} }
_ => unreachable!(),
};
}
fn finish_search(&mut self) { fn finish_search(&mut self) {
assert!(self.state.is_search()); assert!(self.state.is_search());
@ -345,6 +355,42 @@ mod tests {
music_hoard music_hoard
} }
#[test]
fn app_state() {
let mut state = AppPublicState::Browse(());
assert!(state.is_browse());
assert!(state.as_mut().is_browse());
let mut state = AppPublicState::Info(());
assert!(state.is_info());
assert!(state.as_mut().is_info());
let mut state = AppPublicState::Reload(());
assert!(state.is_reload());
assert!(state.as_mut().is_reload());
let mut state = AppPublicState::Search(String::from("get rekt"));
assert!(state.is_search());
assert!(state.as_mut().is_search());
assert_eq!(state.unwrap_search().as_str(), "get rekt");
let mut state = AppPublicState::Error(String::new());
assert!(state.is_error());
assert!(state.as_mut().is_error());
let mut state = AppPublicState::Critical(String::new());
assert!(matches!(state, AppState::Critical(_)));
assert!(matches!(state.as_mut(), AppState::Critical(_)));
}
#[test]
#[should_panic]
fn app_state_unwrap_search_panic() {
let state = AppPublicState::Browse(());
assert!(state.is_browse());
state.unwrap_search();
}
#[test] #[test]
fn running_quit() { fn running_quit() {
let mut app = App::new(music_hoard(COLLECTION.to_owned())); let mut app = App::new(music_hoard(COLLECTION.to_owned()));
@ -767,4 +813,60 @@ mod tests {
app.dismiss_error(); app.dismiss_error();
assert!(app.state().is_browse()); assert!(app.state().is_browse());
} }
#[test]
fn search() {
let mut app = App::new(music_hoard(COLLECTION.to_owned()));
assert!(app.state().is_browse());
app.increment_selection(Delta::Line);
app.increment_category();
assert_eq!(app.selection.active, Category::Album);
assert_eq!(app.selection.artist.state.list.selected(), Some(1));
app.begin_search();
assert!(app.state().is_search());
assert_eq!(app.selection.active, Category::Album);
assert_eq!(app.selection.artist.state.list.selected(), Some(0));
app.append_character('a');
app.append_character('l');
app.append_character('b');
app.append_character('u');
app.append_character('m');
app.append_character('_');
app.append_character('a');
app.append_character('r');
app.append_character('t');
app.append_character('i');
app.append_character('s');
app.append_character('t');
app.append_character(' ');
assert_eq!(app.selection.active, Category::Album);
assert_eq!(app.selection.artist.state.list.selected(), Some(0));
app.append_character('c');
assert_eq!(app.selection.active, Category::Album);
assert_eq!(app.selection.artist.state.list.selected(), Some(2));
app.remove_character();
assert_eq!(app.selection.active, Category::Album);
assert_eq!(app.selection.artist.state.list.selected(), Some(0));
app.append_character('b');
assert_eq!(app.selection.active, Category::Album);
assert_eq!(app.selection.artist.state.list.selected(), Some(1));
app.finish_search();
assert!(app.state().is_browse());
assert_eq!(app.selection.active, Category::Album);
assert_eq!(app.selection.artist.state.list.selected(), Some(1));
}
} }

View File

@ -192,11 +192,12 @@ impl ArtistSelection {
} }
} }
// FIXME: think about converting punctuation characters to some common character.
fn incremental_search(&mut self, artists: &[Artist], artist_name: &str) { fn incremental_search(&mut self, artists: &[Artist], artist_name: &str) {
if let Some(index) = self.state.list.selected() { if let Some(index) = self.state.list.selected() {
let case_sensitive = artist_name let case_sensitive = artist_name
.chars() .chars()
.any(|ch| !(ch.is_lowercase() || ch.is_whitespace())); .any(|ch| !(ch.is_lowercase() || ch.is_whitespace() || ch.is_ascii_punctuation()));
let slice = &artists[index..]; let slice = &artists[index..];
let result = if case_sensitive { let result = if case_sensitive {
@ -807,4 +808,51 @@ mod tests {
sel.reinitialise(&[], active_artist); sel.reinitialise(&[], active_artist);
assert_eq!(sel, expected); assert_eq!(sel, expected);
} }
#[test]
fn artist_incremental_search() {
let artists = &COLLECTION;
let mut sel = ArtistSelection::initialise(&[]);
assert_eq!(sel.state.list.selected(), None);
sel.incremental_search(artists, "album_artist a");
assert_eq!(sel.state.list.selected(), None);
let mut sel = ArtistSelection::initialise(artists);
assert_eq!(sel.state.list.selected(), Some(0));
sel.incremental_search(artists, "album_artist a");
assert_eq!(sel.state.list.selected(), Some(0));
sel.reinitialise(artists, None);
assert_eq!(sel.state.list.selected(), Some(0));
sel.incremental_search(artists, "album_artist b");
assert_eq!(sel.state.list.selected(), Some(1));
sel.reinitialise(artists, None);
assert_eq!(sel.state.list.selected(), Some(0));
sel.incremental_search(artists, "Album_Artist B");
assert_eq!(sel.state.list.selected(), Some(1));
sel.reinitialise(artists, None);
assert_eq!(sel.state.list.selected(), Some(0));
sel.incremental_search(artists, "album_artist ba");
assert_eq!(sel.state.list.selected(), Some(2));
sel.reinitialise(artists, None);
assert_eq!(sel.state.list.selected(), Some(0));
sel.incremental_search(artists, "album_artist c");
assert_eq!(sel.state.list.selected(), Some(2));
sel.reinitialise(artists, None);
assert_eq!(sel.state.list.selected(), Some(0));
sel.incremental_search(artists, "album_artist d");
assert_eq!(sel.state.list.selected(), Some(3));
}
} }

View File

@ -724,6 +724,10 @@ mod tests {
app.state = &AppState::Reload(()); app.state = &AppState::Reload(());
terminal.draw(|frame| Ui::render(&mut app, frame)).unwrap(); terminal.draw(|frame| Ui::render(&mut app, frame)).unwrap();
let binding = AppState::Search(String::new());
app.state = &binding;
terminal.draw(|frame| Ui::render(&mut app, frame)).unwrap();
let binding = AppState::Error(String::from("get rekt scrub")); let binding = AppState::Error(String::from("get rekt scrub"));
app.state = &binding; app.state = &binding;
terminal.draw(|frame| Ui::render(&mut app, frame)).unwrap(); terminal.draw(|frame| Ui::render(&mut app, frame)).unwrap();