From 32b09b2f52bc8c14052c5b7318e722a25ff59275 Mon Sep 17 00:00:00 2001 From: Wojciech Kozlowski Date: Sat, 28 Sep 2024 10:46:29 +0200 Subject: [PATCH] Add info as substruct of meta --- src/bin/musichoard-edit.rs | 5 +- src/core/collection/artist.rs | 160 ++++++++---------- src/core/musichoard/database.rs | 52 +++--- src/core/testmod.rs | 2 +- src/external/database/serde/deserialize.rs | 8 +- src/external/database/serde/serialize.rs | 3 +- src/external/musicbrainz/api/mod.rs | 6 +- src/testmod/full.rs | 72 ++++---- src/testmod/library.rs | 24 ++- src/tui/app/machine/fetch_state.rs | 2 +- src/tui/app/machine/match_state.rs | 2 +- src/tui/app/machine/search_state.rs | 2 +- src/tui/lib/external/musicbrainz/api/mod.rs | 14 +- .../lib/external/musicbrainz/daemon/mod.rs | 4 +- src/tui/testmod.rs | 2 +- src/tui/ui/info_state.rs | 4 +- tests/testlib.rs | 118 +++++++------ 17 files changed, 247 insertions(+), 233 deletions(-) diff --git a/src/bin/musichoard-edit.rs b/src/bin/musichoard-edit.rs index 0a76047..3941786c 100644 --- a/src/bin/musichoard-edit.rs +++ b/src/bin/musichoard-edit.rs @@ -171,10 +171,7 @@ impl SortCommand { fn handle(self, music_hoard: &mut MH, artist_name: &str) { match self { SortCommand::Set(artist_sort_value) => music_hoard - .set_artist_sort( - ArtistId::new(artist_name), - String::from(artist_sort_value.sort), - ) + .set_artist_sort(ArtistId::new(artist_name), artist_sort_value.sort) .expect("faild to set artist sort name"), SortCommand::Clear => music_hoard .clear_artist_sort(ArtistId::new(artist_name)) diff --git a/src/core/collection/artist.rs b/src/core/collection/artist.rs index 87364b8..7c8cc09 100644 --- a/src/core/collection/artist.rs +++ b/src/core/collection/artist.rs @@ -22,6 +22,12 @@ pub struct Artist { pub struct ArtistMeta { pub id: ArtistId, pub sort: Option, + pub info: ArtistInfo, +} + +/// Artist non-identifier metadata. +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct ArtistInfo { pub musicbrainz: MbRefOption, pub properties: HashMap>, } @@ -75,8 +81,10 @@ impl ArtistMeta { ArtistMeta { id: id.into(), sort: None, - musicbrainz: MbRefOption::None, - properties: HashMap::new(), + info: ArtistInfo { + musicbrainz: MbRefOption::None, + properties: HashMap::new(), + }, } } @@ -91,7 +99,9 @@ impl ArtistMeta { pub fn clear_sort_key(&mut self) { self.sort.take(); } +} +impl ArtistInfo { pub fn set_musicbrainz_ref(&mut self, mbref: MbRefOption) { self.musicbrainz = mbref } @@ -162,6 +172,12 @@ impl Merge for ArtistMeta { assert_eq!(self.id, other.id); self.sort = self.sort.take().or(other.sort); + self.info.merge_in_place(other.info); + } +} + +impl Merge for ArtistInfo { + fn merge_in_place(&mut self, other: Self) { self.musicbrainz = self.musicbrainz.take().or(other.musicbrainz); self.properties.merge_in_place(other.properties); } @@ -256,160 +272,132 @@ mod tests { let mut artist = Artist::new(ArtistId::new("an artist")); let mut expected: MbRefOption = MbRefOption::None; - assert_eq!(artist.meta.musicbrainz, expected); + assert_eq!(artist.meta.info.musicbrainz, expected); // Setting a URL on an artist. - artist.meta.set_musicbrainz_ref(MbRefOption::Some( + artist.meta.info.set_musicbrainz_ref(MbRefOption::Some( MbArtistRef::from_url_str(MUSICBRAINZ).unwrap(), )); expected.replace(MbArtistRef::from_url_str(MUSICBRAINZ).unwrap()); - assert_eq!(artist.meta.musicbrainz, expected); + assert_eq!(artist.meta.info.musicbrainz, expected); - artist.meta.set_musicbrainz_ref(MbRefOption::Some( + artist.meta.info.set_musicbrainz_ref(MbRefOption::Some( MbArtistRef::from_url_str(MUSICBRAINZ).unwrap(), )); - assert_eq!(artist.meta.musicbrainz, expected); + assert_eq!(artist.meta.info.musicbrainz, expected); - artist.meta.set_musicbrainz_ref(MbRefOption::Some( + artist.meta.info.set_musicbrainz_ref(MbRefOption::Some( MbArtistRef::from_url_str(MUSICBRAINZ_2).unwrap(), )); expected.replace(MbArtistRef::from_url_str(MUSICBRAINZ_2).unwrap()); - assert_eq!(artist.meta.musicbrainz, expected); + assert_eq!(artist.meta.info.musicbrainz, expected); // Clearing URLs. - artist.meta.clear_musicbrainz_ref(); + artist.meta.info.clear_musicbrainz_ref(); expected.take(); - assert_eq!(artist.meta.musicbrainz, expected); + assert_eq!(artist.meta.info.musicbrainz, expected); } #[test] fn add_to_remove_from_property() { let mut artist = Artist::new(ArtistId::new("an artist")); + let info = &mut artist.meta.info; let mut expected: Vec = vec![]; - assert!(artist.meta.properties.is_empty()); + assert!(info.properties.is_empty()); // Adding a single URL. - artist - .meta - .add_to_property("MusicButler", vec![MUSICBUTLER]); + info.add_to_property("MusicButler", vec![MUSICBUTLER]); expected.push(MUSICBUTLER.to_owned()); - assert_eq!(artist.meta.properties.get("MusicButler"), Some(&expected)); + assert_eq!(info.properties.get("MusicButler"), Some(&expected)); // Adding a URL that already exists is ok, but does not do anything. - artist - .meta - .add_to_property("MusicButler", vec![MUSICBUTLER]); - assert_eq!(artist.meta.properties.get("MusicButler"), Some(&expected)); + info.add_to_property("MusicButler", vec![MUSICBUTLER]); + assert_eq!(info.properties.get("MusicButler"), Some(&expected)); // Adding another single URL. - artist - .meta - .add_to_property("MusicButler", vec![MUSICBUTLER_2]); + info.add_to_property("MusicButler", vec![MUSICBUTLER_2]); expected.push(MUSICBUTLER_2.to_owned()); - assert_eq!(artist.meta.properties.get("MusicButler"), Some(&expected)); + assert_eq!(info.properties.get("MusicButler"), Some(&expected)); - artist - .meta - .add_to_property("MusicButler", vec![MUSICBUTLER_2]); - assert_eq!(artist.meta.properties.get("MusicButler"), Some(&expected)); + info.add_to_property("MusicButler", vec![MUSICBUTLER_2]); + assert_eq!(info.properties.get("MusicButler"), Some(&expected)); // Removing a URL. - artist - .meta - .remove_from_property("MusicButler", vec![MUSICBUTLER]); + info.remove_from_property("MusicButler", vec![MUSICBUTLER]); expected.retain(|url| url != MUSICBUTLER); - assert_eq!(artist.meta.properties.get("MusicButler"), Some(&expected)); + assert_eq!(info.properties.get("MusicButler"), Some(&expected)); // Removing URls that do not exist is okay, they will be ignored. - artist - .meta - .remove_from_property("MusicButler", vec![MUSICBUTLER]); - assert_eq!(artist.meta.properties.get("MusicButler"), Some(&expected)); + info.remove_from_property("MusicButler", vec![MUSICBUTLER]); + assert_eq!(info.properties.get("MusicButler"), Some(&expected)); // Removing a URL. - artist - .meta - .remove_from_property("MusicButler", vec![MUSICBUTLER_2]); + info.remove_from_property("MusicButler", vec![MUSICBUTLER_2]); expected.retain(|url| url.as_str() != MUSICBUTLER_2); - assert!(artist.meta.properties.is_empty()); + assert!(info.properties.is_empty()); - artist - .meta - .remove_from_property("MusicButler", vec![MUSICBUTLER_2]); - assert!(artist.meta.properties.is_empty()); + info.remove_from_property("MusicButler", vec![MUSICBUTLER_2]); + assert!(info.properties.is_empty()); // Adding URLs if some exist is okay, they will be ignored. - artist - .meta - .add_to_property("MusicButler", vec![MUSICBUTLER]); + info.add_to_property("MusicButler", vec![MUSICBUTLER]); expected.push(MUSICBUTLER.to_owned()); - assert_eq!(artist.meta.properties.get("MusicButler"), Some(&expected)); + assert_eq!(info.properties.get("MusicButler"), Some(&expected)); - artist - .meta - .add_to_property("MusicButler", vec![MUSICBUTLER, MUSICBUTLER_2]); + info.add_to_property("MusicButler", vec![MUSICBUTLER, MUSICBUTLER_2]); expected.push(MUSICBUTLER_2.to_owned()); - assert_eq!(artist.meta.properties.get("MusicButler"), Some(&expected)); + assert_eq!(info.properties.get("MusicButler"), Some(&expected)); // Removing URLs if some do not exist is okay, they will be ignored. - artist - .meta - .remove_from_property("MusicButler", vec![MUSICBUTLER]); + info.remove_from_property("MusicButler", vec![MUSICBUTLER]); expected.retain(|url| url.as_str() != MUSICBUTLER); - assert_eq!(artist.meta.properties.get("MusicButler"), Some(&expected)); + assert_eq!(info.properties.get("MusicButler"), Some(&expected)); - artist - .meta - .remove_from_property("MusicButler", vec![MUSICBUTLER, MUSICBUTLER_2]); + info.remove_from_property("MusicButler", vec![MUSICBUTLER, MUSICBUTLER_2]); expected.retain(|url| url.as_str() != MUSICBUTLER_2); - assert!(artist.meta.properties.is_empty()); + assert!(info.properties.is_empty()); // Adding mutliple URLs without clashes. - artist - .meta - .add_to_property("MusicButler", vec![MUSICBUTLER, MUSICBUTLER_2]); + info.add_to_property("MusicButler", vec![MUSICBUTLER, MUSICBUTLER_2]); expected.push(MUSICBUTLER.to_owned()); expected.push(MUSICBUTLER_2.to_owned()); - assert_eq!(artist.meta.properties.get("MusicButler"), Some(&expected)); + assert_eq!(info.properties.get("MusicButler"), Some(&expected)); // Removing multiple URLs without clashes. - artist - .meta - .remove_from_property("MusicButler", vec![MUSICBUTLER, MUSICBUTLER_2]); + info.remove_from_property("MusicButler", vec![MUSICBUTLER, MUSICBUTLER_2]); expected.clear(); - assert!(artist.meta.properties.is_empty()); + assert!(info.properties.is_empty()); } #[test] fn set_clear_musicbutler_urls() { let mut artist = Artist::new(ArtistId::new("an artist")); + let info = &mut artist.meta.info; let mut expected: Vec = vec![]; - assert!(artist.meta.properties.is_empty()); + assert!(info.properties.is_empty()); // Set URLs. - artist.meta.set_property("MusicButler", vec![MUSICBUTLER]); + info.set_property("MusicButler", vec![MUSICBUTLER]); expected.push(MUSICBUTLER.to_owned()); - assert_eq!(artist.meta.properties.get("MusicButler"), Some(&expected)); + assert_eq!(info.properties.get("MusicButler"), Some(&expected)); - artist.meta.set_property("MusicButler", vec![MUSICBUTLER_2]); + info.set_property("MusicButler", vec![MUSICBUTLER_2]); expected.clear(); expected.push(MUSICBUTLER_2.to_owned()); - assert_eq!(artist.meta.properties.get("MusicButler"), Some(&expected)); + assert_eq!(info.properties.get("MusicButler"), Some(&expected)); - artist - .meta - .set_property("MusicButler", vec![MUSICBUTLER, MUSICBUTLER_2]); + info.set_property("MusicButler", vec![MUSICBUTLER, MUSICBUTLER_2]); expected.clear(); expected.push(MUSICBUTLER.to_owned()); expected.push(MUSICBUTLER_2.to_owned()); - assert_eq!(artist.meta.properties.get("MusicButler"), Some(&expected)); + assert_eq!(info.properties.get("MusicButler"), Some(&expected)); // Clear URLs. - artist.meta.clear_property("MusicButler"); + info.clear_property("MusicButler"); expected.clear(); - assert!(artist.meta.properties.is_empty()); + assert!(info.properties.is_empty()); } #[test] @@ -417,14 +405,15 @@ mod tests { let left = FULL_COLLECTION[0].to_owned(); let mut right = FULL_COLLECTION[1].to_owned(); right.meta.id = left.meta.id.clone(); - right.meta.musicbrainz = MbRefOption::None; - right.meta.properties = HashMap::new(); + right.meta.info.musicbrainz = MbRefOption::None; + right.meta.info.properties = HashMap::new(); let mut expected = left.clone(); - expected.meta.properties = expected + expected.meta.info.properties = expected .meta + .info .properties - .merge(right.clone().meta.properties); + .merge(right.clone().meta.info.properties); expected.albums.append(&mut right.albums.clone()); expected.albums.sort_unstable(); @@ -445,10 +434,11 @@ mod tests { left.albums.sort_unstable(); let mut expected = left.clone(); - expected.meta.properties = expected + expected.meta.info.properties = expected .meta + .info .properties - .merge(right.clone().meta.properties); + .merge(right.clone().meta.info.properties); expected.albums.append(&mut right.albums.clone()); expected.albums.sort_unstable(); expected.albums.dedup(); diff --git a/src/core/musichoard/database.rs b/src/core/musichoard/database.rs index 4ef54e6..d3193ce 100644 --- a/src/core/musichoard/database.rs +++ b/src/core/musichoard/database.rs @@ -165,7 +165,7 @@ impl IMusicHoardDatabase for MusicHoard, ) -> Result<(), Error> { self.update_artist(artist_id.as_ref(), |artist| { - artist.meta.set_musicbrainz_ref(mbid) + artist.meta.info.set_musicbrainz_ref(mbid) }) } @@ -174,7 +174,7 @@ impl IMusicHoardDatabase for MusicHoard Result<(), Error> { self.update_artist(artist_id.as_ref(), |artist| { - artist.meta.clear_musicbrainz_ref() + artist.meta.info.clear_musicbrainz_ref() }) } @@ -185,7 +185,7 @@ impl IMusicHoardDatabase for MusicHoard, ) -> Result<(), Error> { self.update_artist(artist_id.as_ref(), |artist| { - artist.meta.add_to_property(property, values) + artist.meta.info.add_to_property(property, values) }) } @@ -196,7 +196,7 @@ impl IMusicHoardDatabase for MusicHoard, ) -> Result<(), Error> { self.update_artist(artist_id.as_ref(), |artist| { - artist.meta.remove_from_property(property, values) + artist.meta.info.remove_from_property(property, values) }) } @@ -207,7 +207,7 @@ impl IMusicHoardDatabase for MusicHoard, ) -> Result<(), Error> { self.update_artist(artist_id.as_ref(), |artist| { - artist.meta.set_property(property, values) + artist.meta.info.set_property(property, values) }) } @@ -217,7 +217,7 @@ impl IMusicHoardDatabase for MusicHoard Result<(), Error> { self.update_artist(artist_id.as_ref(), |artist| { - artist.meta.clear_property(property) + artist.meta.info.clear_property(property) }) } @@ -533,7 +533,7 @@ mod tests { assert!(music_hoard.add_artist(artist_id.clone()).is_ok()); let mut expected: MbRefOption = MbRefOption::None; - assert_eq!(music_hoard.collection[0].meta.musicbrainz, expected); + assert_eq!(music_hoard.collection[0].meta.info.musicbrainz, expected); let mbref = MbRefOption::Some(MbArtistRef::from_uuid_str(MBID).unwrap()); @@ -541,23 +541,23 @@ mod tests { assert!(music_hoard .set_artist_musicbrainz(&artist_id_2, mbref.clone()) .is_err()); - assert_eq!(music_hoard.collection[0].meta.musicbrainz, expected); + assert_eq!(music_hoard.collection[0].meta.info.musicbrainz, expected); // Setting a URL on an artist. assert!(music_hoard .set_artist_musicbrainz(&artist_id, mbref.clone()) .is_ok()); expected.replace(MbArtistRef::from_uuid_str(MBID).unwrap()); - assert_eq!(music_hoard.collection[0].meta.musicbrainz, expected); + assert_eq!(music_hoard.collection[0].meta.info.musicbrainz, expected); // Clearing URLs on an artist that does not exist is an error. assert!(music_hoard.clear_artist_musicbrainz(&artist_id_2).is_err()); - assert_eq!(music_hoard.collection[0].meta.musicbrainz, expected); + assert_eq!(music_hoard.collection[0].meta.info.musicbrainz, expected); // Clearing URLs. assert!(music_hoard.clear_artist_musicbrainz(&artist_id).is_ok()); expected.take(); - assert_eq!(music_hoard.collection[0].meta.musicbrainz, expected); + assert_eq!(music_hoard.collection[0].meta.info.musicbrainz, expected); } #[test] @@ -573,13 +573,13 @@ mod tests { assert!(music_hoard.add_artist(artist_id.clone()).is_ok()); let mut expected: Vec = vec![]; - assert!(music_hoard.collection[0].meta.properties.is_empty()); + assert!(music_hoard.collection[0].meta.info.properties.is_empty()); // Adding URLs to an artist not in the collection is an error. assert!(music_hoard .add_to_artist_property(&artist_id_2, "MusicButler", vec![MUSICBUTLER]) .is_err()); - assert!(music_hoard.collection[0].meta.properties.is_empty()); + assert!(music_hoard.collection[0].meta.info.properties.is_empty()); // Adding mutliple URLs without clashes. assert!(music_hoard @@ -587,19 +587,15 @@ mod tests { .is_ok()); expected.push(MUSICBUTLER.to_owned()); expected.push(MUSICBUTLER_2.to_owned()); - assert_eq!( - music_hoard.collection[0].meta.properties.get("MusicButler"), - Some(&expected) - ); + let info = &music_hoard.collection[0].meta.info; + assert_eq!(info.properties.get("MusicButler"), Some(&expected)); // Removing URLs from an artist not in the collection is an error. assert!(music_hoard .remove_from_artist_property(&artist_id_2, "MusicButler", vec![MUSICBUTLER]) .is_err()); - assert_eq!( - music_hoard.collection[0].meta.properties.get("MusicButler"), - Some(&expected) - ); + let info = &music_hoard.collection[0].meta.info; + assert_eq!(info.properties.get("MusicButler"), Some(&expected)); // Removing multiple URLs without clashes. assert!(music_hoard @@ -610,7 +606,7 @@ mod tests { ) .is_ok()); expected.clear(); - assert!(music_hoard.collection[0].meta.properties.is_empty()); + assert!(music_hoard.collection[0].meta.info.properties.is_empty()); } #[test] @@ -626,13 +622,13 @@ mod tests { assert!(music_hoard.add_artist(artist_id.clone()).is_ok()); let mut expected: Vec = vec![]; - assert!(music_hoard.collection[0].meta.properties.is_empty()); + assert!(music_hoard.collection[0].meta.info.properties.is_empty()); // Seting URL on an artist not in the collection is an error. assert!(music_hoard .set_artist_property(&artist_id_2, "MusicButler", vec![MUSICBUTLER]) .is_err()); - assert!(music_hoard.collection[0].meta.properties.is_empty()); + assert!(music_hoard.collection[0].meta.info.properties.is_empty()); // Set URLs. assert!(music_hoard @@ -641,10 +637,8 @@ mod tests { expected.clear(); expected.push(MUSICBUTLER.to_owned()); expected.push(MUSICBUTLER_2.to_owned()); - assert_eq!( - music_hoard.collection[0].meta.properties.get("MusicButler"), - Some(&expected) - ); + let info = &music_hoard.collection[0].meta.info; + assert_eq!(info.properties.get("MusicButler"), Some(&expected)); // Clearing URLs on an artist that does not exist is an error. assert!(music_hoard @@ -656,7 +650,7 @@ mod tests { .clear_artist_property(&artist_id, "MusicButler") .is_ok()); expected.clear(); - assert!(music_hoard.collection[0].meta.properties.is_empty()); + assert!(music_hoard.collection[0].meta.info.properties.is_empty()); } #[test] diff --git a/src/core/testmod.rs b/src/core/testmod.rs index b7f1ca0..71b3104 100644 --- a/src/core/testmod.rs +++ b/src/core/testmod.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use crate::core::collection::{ album::{Album, AlbumId, AlbumMeta, AlbumPrimaryType, AlbumSeq}, - artist::{Artist, ArtistId, ArtistMeta}, + artist::{Artist, ArtistId, ArtistInfo, ArtistMeta}, musicbrainz::{MbAlbumRef, MbArtistRef, MbRefOption}, track::{Track, TrackFormat, TrackId, TrackNum, TrackQuality}, }; diff --git a/src/external/database/serde/deserialize.rs b/src/external/database/serde/deserialize.rs index 9a14061..0995421 100644 --- a/src/external/database/serde/deserialize.rs +++ b/src/external/database/serde/deserialize.rs @@ -5,7 +5,7 @@ use serde::{de::Visitor, Deserialize, Deserializer}; use crate::{ collection::{ album::AlbumMeta, - artist::ArtistMeta, + artist::{ArtistInfo, ArtistMeta}, musicbrainz::{MbAlbumRef, MbArtistRef, MbRefOption, Mbid}, }, core::collection::{ @@ -115,8 +115,10 @@ impl From for Artist { meta: ArtistMeta { id: ArtistId::new(artist.name), sort: artist.sort, - musicbrainz: artist.musicbrainz.into(), - properties: artist.properties, + info: ArtistInfo { + musicbrainz: artist.musicbrainz.into(), + properties: artist.properties, + }, }, albums: artist.albums.into_iter().map(Into::into).collect(), } diff --git a/src/external/database/serde/serialize.rs b/src/external/database/serde/serialize.rs index 0de9be4..8590c90 100644 --- a/src/external/database/serde/serialize.rs +++ b/src/external/database/serde/serialize.rs @@ -73,9 +73,10 @@ impl<'a> From<&'a Artist> for SerializeArtist<'a> { SerializeArtist { name: &artist.meta.id.name, sort: artist.meta.sort.as_deref(), - musicbrainz: (&artist.meta.musicbrainz).into(), + musicbrainz: (&artist.meta.info.musicbrainz).into(), properties: artist .meta + .info .properties .iter() .map(|(k, v)| (k.as_ref(), v)) diff --git a/src/external/musicbrainz/api/mod.rs b/src/external/musicbrainz/api/mod.rs index 24ce9d9..70e9299 100644 --- a/src/external/musicbrainz/api/mod.rs +++ b/src/external/musicbrainz/api/mod.rs @@ -79,8 +79,8 @@ impl From for MbArtistMeta { fn from(value: SerdeMbArtistMeta) -> Self { MbArtistMeta { id: value.id.into(), - name: value.name.into(), - sort_name: value.sort_name.into(), + name: value.name, + sort_name: value.sort_name, disambiguation: value.disambiguation, } } @@ -109,7 +109,7 @@ impl From for MbReleaseGroupMeta { fn from(value: SerdeMbReleaseGroupMeta) -> Self { MbReleaseGroupMeta { id: value.id.into(), - title: value.title.into(), + title: value.title, first_release_date: value.first_release_date.into(), primary_type: value.primary_type.into(), secondary_types: value diff --git a/src/testmod/full.rs b/src/testmod/full.rs index 9ed3ae7..b23ea9b 100644 --- a/src/testmod/full.rs +++ b/src/testmod/full.rs @@ -7,19 +7,21 @@ macro_rules! full_collection { name: "Album_Artist ‘A’".to_string(), }, sort: None, - musicbrainz: MbRefOption::Some(MbArtistRef::from_url_str( - "https://musicbrainz.org/artist/00000000-0000-0000-0000-000000000000" - ).unwrap()), - properties: HashMap::from([ - (String::from("MusicButler"), vec![ - String::from("https://www.musicbutler.io/artist-page/000000000"), + info: ArtistInfo { + musicbrainz: MbRefOption::Some(MbArtistRef::from_url_str( + "https://musicbrainz.org/artist/00000000-0000-0000-0000-000000000000" + ).unwrap()), + properties: HashMap::from([ + (String::from("MusicButler"), vec![ + String::from("https://www.musicbutler.io/artist-page/000000000"), + ]), + (String::from("Qobuz"), vec![ + String::from( + "https://www.qobuz.com/nl-nl/interpreter/artist-a/download-streaming-albums", + ) + ]), ]), - (String::from("Qobuz"), vec![ - String::from( - "https://www.qobuz.com/nl-nl/interpreter/artist-a/download-streaming-albums", - ) - ]), - ]), + }, }, albums: vec![ Album { @@ -129,23 +131,25 @@ macro_rules! full_collection { name: "Album_Artist ‘B’".to_string(), }, sort: None, - musicbrainz: MbRefOption::Some(MbArtistRef::from_url_str( - "https://musicbrainz.org/artist/11111111-1111-1111-1111-111111111111" - ).unwrap()), - properties: HashMap::from([ - (String::from("MusicButler"), vec![ - String::from("https://www.musicbutler.io/artist-page/111111111"), - String::from("https://www.musicbutler.io/artist-page/111111112"), + info: ArtistInfo { + musicbrainz: MbRefOption::Some(MbArtistRef::from_url_str( + "https://musicbrainz.org/artist/11111111-1111-1111-1111-111111111111" + ).unwrap()), + properties: HashMap::from([ + (String::from("MusicButler"), vec![ + String::from("https://www.musicbutler.io/artist-page/111111111"), + String::from("https://www.musicbutler.io/artist-page/111111112"), + ]), + (String::from("Bandcamp"), vec![ + String::from("https://artist-b.bandcamp.com/") + ]), + (String::from("Qobuz"), vec![ + String::from( + "https://www.qobuz.com/nl-nl/interpreter/artist-b/download-streaming-albums", + ) + ]), ]), - (String::from("Bandcamp"), vec![ - String::from("https://artist-b.bandcamp.com/") - ]), - (String::from("Qobuz"), vec![ - String::from( - "https://www.qobuz.com/nl-nl/interpreter/artist-b/download-streaming-albums", - ) - ]), - ]), + }, }, albums: vec![ Album { @@ -316,8 +320,10 @@ macro_rules! full_collection { name: "The Album_Artist ‘C’".to_string(), }, sort: Some("Album_Artist ‘C’, The".to_string()), - musicbrainz: MbRefOption::CannotHaveMbid, - properties: HashMap::new(), + info: ArtistInfo { + musicbrainz: MbRefOption::CannotHaveMbid, + properties: HashMap::new(), + }, }, albums: vec![ Album { @@ -406,8 +412,10 @@ macro_rules! full_collection { name: "Album_Artist ‘D’".to_string(), }, sort: None, - musicbrainz: MbRefOption::None, - properties: HashMap::new(), + info: ArtistInfo { + musicbrainz: MbRefOption::None, + properties: HashMap::new(), + }, }, albums: vec![ Album { diff --git a/src/testmod/library.rs b/src/testmod/library.rs index 063e9f1..1fb8ae7 100644 --- a/src/testmod/library.rs +++ b/src/testmod/library.rs @@ -8,8 +8,10 @@ macro_rules! library_collection { name: "Album_Artist ‘A’".to_string(), }, sort: None, - musicbrainz: MbRefOption::None, - properties: HashMap::new(), + info: ArtistInfo { + musicbrainz: MbRefOption::None, + properties: HashMap::new(), + }, }, albums: vec![ Album { @@ -117,8 +119,10 @@ macro_rules! library_collection { name: "Album_Artist ‘B’".to_string(), }, sort: None, - musicbrainz: MbRefOption::None, - properties: HashMap::new(), + info: ArtistInfo { + musicbrainz: MbRefOption::None, + properties: HashMap::new(), + }, }, albums: vec![ Album { @@ -285,8 +289,10 @@ macro_rules! library_collection { name: "The Album_Artist ‘C’".to_string(), }, sort: Some("Album_Artist ‘C’, The".to_string()), - musicbrainz: MbRefOption::None, - properties: HashMap::new(), + info: ArtistInfo { + musicbrainz: MbRefOption::None, + properties: HashMap::new(), + }, }, albums: vec![ Album { @@ -375,8 +381,10 @@ macro_rules! library_collection { name: "Album_Artist ‘D’".to_string(), }, sort: None, - musicbrainz: MbRefOption::None, - properties: HashMap::new(), + info: ArtistInfo { + musicbrainz: MbRefOption::None, + properties: HashMap::new(), + }, }, albums: vec![ Album { diff --git a/src/tui/app/machine/fetch_state.rs b/src/tui/app/machine/fetch_state.rs index a56aff1..5fde367 100644 --- a/src/tui/app/machine/fetch_state.rs +++ b/src/tui/app/machine/fetch_state.rs @@ -156,7 +156,7 @@ impl AppMachine { result_sender: ResultSender, artist: &Artist, ) -> Result<(), FetchError> { - let requests = match artist.meta.musicbrainz { + let requests = match artist.meta.info.musicbrainz { MbRefOption::Some(ref arid) => { let arid = arid.mbid(); let albums = artist.albums.iter(); diff --git a/src/tui/app/machine/match_state.rs b/src/tui/app/machine/match_state.rs index 6d0c980..ea80453 100644 --- a/src/tui/app/machine/match_state.rs +++ b/src/tui/app/machine/match_state.rs @@ -27,7 +27,7 @@ macro_rules! item_option_artist_set { meta: &ArtistMeta, ) -> Result<(), musichoard::Error> { let mbref = match self { - MatchOption::Some(m) => m.item.musicbrainz, + MatchOption::Some(m) => m.item.info.musicbrainz, MatchOption::CannotHaveMbid => MbRefOption::CannotHaveMbid, MatchOption::ManualInputMbid => panic!(), }; diff --git a/src/tui/app/machine/search_state.rs b/src/tui/app/machine/search_state.rs index 05f9b23..ce6d519 100644 --- a/src/tui/app/machine/search_state.rs +++ b/src/tui/app/machine/search_state.rs @@ -182,7 +182,7 @@ impl IAppInteractSearchPrivate for AppMachine { if let Some(ref probe_sort) = probe.meta.sort { if !result { - let name = Self::normalize_search(&probe_sort, !case_sens, !char_sens); + let name = Self::normalize_search(probe_sort, !case_sens, !char_sens); result = name.starts_with(search); } } diff --git a/src/tui/lib/external/musicbrainz/api/mod.rs b/src/tui/lib/external/musicbrainz/api/mod.rs index 146ca22..e39fa4c 100644 --- a/src/tui/lib/external/musicbrainz/api/mod.rs +++ b/src/tui/lib/external/musicbrainz/api/mod.rs @@ -5,7 +5,7 @@ use std::collections::HashMap; use musichoard::{ collection::{ album::{AlbumDate, AlbumMeta, AlbumSeq}, - artist::ArtistMeta, + artist::{ArtistInfo, ArtistMeta}, musicbrainz::{MbRefOption, Mbid}, }, external::musicbrainz::{ @@ -98,8 +98,10 @@ fn from_lookup_artist_response(entity: LookupArtistResponse) -> Lookup Mat item: ArtistMeta { id: entity.meta.name.into(), sort, - musicbrainz: MbRefOption::Some(entity.meta.id.into()), - properties: HashMap::new(), + info: ArtistInfo { + musicbrainz: MbRefOption::Some(entity.meta.id.into()), + properties: HashMap::new(), + }, }, disambiguation: entity.meta.disambiguation, } diff --git a/src/tui/lib/external/musicbrainz/daemon/mod.rs b/src/tui/lib/external/musicbrainz/daemon/mod.rs index 91981c6..dc75fd2 100644 --- a/src/tui/lib/external/musicbrainz/daemon/mod.rs +++ b/src/tui/lib/external/musicbrainz/daemon/mod.rs @@ -419,7 +419,7 @@ mod tests { } fn search_albums_requests() -> VecDeque { - let mbref = mb_ref_opt_as_ref(&COLLECTION[1].meta.musicbrainz); + let mbref = mb_ref_opt_as_ref(&COLLECTION[1].meta.info.musicbrainz); let arid = mb_ref_opt_unwrap(mbref).mbid().clone(); let artist_id = COLLECTION[1].meta.id.clone(); @@ -437,7 +437,7 @@ mod tests { } fn album_arid_expectation() -> Mbid { - let mbref = mb_ref_opt_as_ref(&COLLECTION[1].meta.musicbrainz); + let mbref = mb_ref_opt_as_ref(&COLLECTION[1].meta.info.musicbrainz); mb_ref_opt_unwrap(mbref).mbid().clone() } diff --git a/src/tui/testmod.rs b/src/tui/testmod.rs index ba3955a..b6483af 100644 --- a/src/tui/testmod.rs +++ b/src/tui/testmod.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use musichoard::collection::{ album::{Album, AlbumId, AlbumMeta, AlbumPrimaryType, AlbumSeq}, - artist::{Artist, ArtistId, ArtistMeta}, + artist::{Artist, ArtistId, ArtistInfo, ArtistMeta}, musicbrainz::{MbAlbumRef, MbArtistRef, MbRefOption}, track::{Track, TrackFormat, TrackId, TrackNum, TrackQuality}, }; diff --git a/src/tui/ui/info_state.rs b/src/tui/ui/info_state.rs index 8936d90..7d00c01 100644 --- a/src/tui/ui/info_state.rs +++ b/src/tui/ui/info_state.rs @@ -76,10 +76,10 @@ impl<'a> ArtistOverlay<'a> { Properties: {}", artist.map(|a| a.meta.id.name.as_str()).unwrap_or(""), artist - .map(|a| UiDisplay::display_mb_ref_option_as_url(&a.meta.musicbrainz)) + .map(|a| UiDisplay::display_mb_ref_option_as_url(&a.meta.info.musicbrainz)) .unwrap_or_default(), Self::opt_hashmap_to_string( - artist.map(|a| &a.meta.properties), + artist.map(|a| &a.meta.info.properties), &double_item_indent, &double_list_indent ), diff --git a/tests/testlib.rs b/tests/testlib.rs index 6d1c9e1..4482dcb 100644 --- a/tests/testlib.rs +++ b/tests/testlib.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use musichoard::collection::{ album::{Album, AlbumId, AlbumMeta, AlbumPrimaryType, AlbumSecondaryType, AlbumSeq}, - artist::{Artist, ArtistId, ArtistMeta}, + artist::{Artist, ArtistId, ArtistInfo, ArtistMeta}, musicbrainz::{MbArtistRef, MbRefOption}, track::{Track, TrackFormat, TrackId, TrackNum, TrackQuality}, Collection, @@ -17,20 +17,22 @@ pub static COLLECTION: Lazy> = Lazy::new(|| -> Collection { name: String::from("Аркона"), }, sort: Some(String::from("Arkona")), - musicbrainz: MbRefOption::Some(MbArtistRef::from_url_str( - "https://musicbrainz.org/artist/baad262d-55ef-427a-83c7-f7530964f212" - ).unwrap()), - properties: HashMap::from([ - (String::from("MusicButler"), vec![ - String::from("https://www.musicbutler.io/artist-page/283448581"), + info: ArtistInfo { + musicbrainz: MbRefOption::Some(MbArtistRef::from_url_str( + "https://musicbrainz.org/artist/baad262d-55ef-427a-83c7-f7530964f212" + ).unwrap()), + properties: HashMap::from([ + (String::from("MusicButler"), vec![ + String::from("https://www.musicbutler.io/artist-page/283448581"), + ]), + (String::from("Bandcamp"), vec![ + String::from("https://arkonamoscow.bandcamp.com/"), + ]), + (String::from("Qobuz"), vec![String::from( + "https://www.qobuz.com/nl-nl/interpreter/arkona/download-streaming-albums", + )]), ]), - (String::from("Bandcamp"), vec![ - String::from("https://arkonamoscow.bandcamp.com/"), - ]), - (String::from("Qobuz"), vec![String::from( - "https://www.qobuz.com/nl-nl/interpreter/arkona/download-streaming-albums", - )]), - ]), + }, }, albums: vec![Album { meta: AlbumMeta { @@ -207,17 +209,19 @@ pub static COLLECTION: Lazy> = Lazy::new(|| -> Collection { name: String::from("Eluveitie"), }, sort: None, - musicbrainz: MbRefOption::Some(MbArtistRef::from_url_str( - "https://musicbrainz.org/artist/8000598a-5edb-401c-8e6d-36b167feaf38" - ).unwrap()), - properties: HashMap::from([ - (String::from("MusicButler"), vec![ - String::from("https://www.musicbutler.io/artist-page/269358403"), + info: ArtistInfo { + musicbrainz: MbRefOption::Some(MbArtistRef::from_url_str( + "https://musicbrainz.org/artist/8000598a-5edb-401c-8e6d-36b167feaf38" + ).unwrap()), + properties: HashMap::from([ + (String::from("MusicButler"), vec![ + String::from("https://www.musicbutler.io/artist-page/269358403"), + ]), + (String::from("Qobuz"), vec![String::from( + "https://www.qobuz.com/nl-nl/interpreter/eluveitie/download-streaming-albums", + )]), ]), - (String::from("Qobuz"), vec![String::from( - "https://www.qobuz.com/nl-nl/interpreter/eluveitie/download-streaming-albums", - )]), - ]), + }, }, albums: vec![ Album { @@ -454,17 +458,19 @@ pub static COLLECTION: Lazy> = Lazy::new(|| -> Collection { name: String::from("Frontside"), }, sort: None, - musicbrainz: MbRefOption::Some(MbArtistRef::from_url_str( - "https://musicbrainz.org/artist/3a901353-fccd-4afd-ad01-9c03f451b490" - ).unwrap()), - properties: HashMap::from([ - (String::from("MusicButler"), vec![ - String::from("https://www.musicbutler.io/artist-page/826588800"), + info: ArtistInfo { + musicbrainz: MbRefOption::Some(MbArtistRef::from_url_str( + "https://musicbrainz.org/artist/3a901353-fccd-4afd-ad01-9c03f451b490" + ).unwrap()), + properties: HashMap::from([ + (String::from("MusicButler"), vec![ + String::from("https://www.musicbutler.io/artist-page/826588800"), + ]), + (String::from("Qobuz"), vec![String::from( + "https://www.qobuz.com/nl-nl/interpreter/frontside/download-streaming-albums", + )]), ]), - (String::from("Qobuz"), vec![String::from( - "https://www.qobuz.com/nl-nl/interpreter/frontside/download-streaming-albums", - )]), - ]), + }, }, albums: vec![Album { meta: AlbumMeta { @@ -608,17 +614,19 @@ pub static COLLECTION: Lazy> = Lazy::new(|| -> Collection { name: String::from("Heaven’s Basement"), }, sort: Some(String::from("Heaven’s Basement")), - musicbrainz: MbRefOption::Some(MbArtistRef::from_url_str( - "https://musicbrainz.org/artist/c2c4d56a-d599-4a18-bd2f-ae644e2198cc" - ).unwrap()), - properties: HashMap::from([ - (String::from("MusicButler"), vec![ - String::from("https://www.musicbutler.io/artist-page/291158685"), + info: ArtistInfo { + musicbrainz: MbRefOption::Some(MbArtistRef::from_url_str( + "https://musicbrainz.org/artist/c2c4d56a-d599-4a18-bd2f-ae644e2198cc" + ).unwrap()), + properties: HashMap::from([ + (String::from("MusicButler"), vec![ + String::from("https://www.musicbutler.io/artist-page/291158685"), + ]), + (String::from("Qobuz"), vec![String::from( + "https://www.qobuz.com/nl-nl/interpreter/heaven-s-basement/download-streaming-albums", + )]), ]), - (String::from("Qobuz"), vec![String::from( - "https://www.qobuz.com/nl-nl/interpreter/heaven-s-basement/download-streaming-albums", - )]), - ]), + }, }, albums: vec![Album { meta: AlbumMeta { @@ -742,17 +750,19 @@ pub static COLLECTION: Lazy> = Lazy::new(|| -> Collection { name: String::from("Metallica"), }, sort: None, - musicbrainz: MbRefOption::Some(MbArtistRef::from_url_str( - "https://musicbrainz.org/artist/65f4f0c5-ef9e-490c-aee3-909e7ae6b2ab" - ).unwrap()), - properties: HashMap::from([ - (String::from("MusicButler"), vec![ - String::from("https://www.musicbutler.io/artist-page/3996865"), + info: ArtistInfo { + musicbrainz: MbRefOption::Some(MbArtistRef::from_url_str( + "https://musicbrainz.org/artist/65f4f0c5-ef9e-490c-aee3-909e7ae6b2ab" + ).unwrap()), + properties: HashMap::from([ + (String::from("MusicButler"), vec![ + String::from("https://www.musicbutler.io/artist-page/3996865"), + ]), + (String::from("Qobuz"), vec![String::from( + "https://www.qobuz.com/nl-nl/interpreter/metallica/download-streaming-albums", + )]), ]), - (String::from("Qobuz"), vec![String::from( - "https://www.qobuz.com/nl-nl/interpreter/metallica/download-streaming-albums", - )]), - ]), + }, }, albums: vec![ Album {