Add info as substruct of meta

This commit is contained in:
Wojciech Kozlowski 2024-09-28 10:46:29 +02:00
parent 50779e2a32
commit 32b09b2f52
17 changed files with 247 additions and 233 deletions

View File

@ -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))

View File

@ -22,6 +22,12 @@ pub struct Artist {
pub struct ArtistMeta {
pub id: ArtistId,
pub sort: Option<String>,
pub info: ArtistInfo,
}
/// Artist non-identifier metadata.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ArtistInfo {
pub musicbrainz: MbRefOption<MbArtistRef>,
pub properties: HashMap<String, Vec<String>>,
}
@ -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<MbArtistRef>) {
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<MbArtistRef> = 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<String> = 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<String> = 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();

View File

@ -165,7 +165,7 @@ impl<Database: IDatabase, Library> IMusicHoardDatabase for MusicHoard<Database,
mbid: MbRefOption<MbArtistRef>,
) -> 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<Database: IDatabase, Library> IMusicHoardDatabase for MusicHoard<Database,
artist_id: Id,
) -> 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<Database: IDatabase, Library> IMusicHoardDatabase for MusicHoard<Database,
values: Vec<S>,
) -> 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<Database: IDatabase, Library> IMusicHoardDatabase for MusicHoard<Database,
values: Vec<S>,
) -> 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<Database: IDatabase, Library> IMusicHoardDatabase for MusicHoard<Database,
values: Vec<S>,
) -> 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<Database: IDatabase, Library> IMusicHoardDatabase for MusicHoard<Database,
property: S,
) -> 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<MbArtistRef> = 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<String> = 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<String> = 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]

View File

@ -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},
};

View File

@ -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<DeserializeArtist> 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(),
}

View File

@ -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))

View File

@ -79,8 +79,8 @@ impl From<SerdeMbArtistMeta> 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<SerdeMbReleaseGroupMeta> 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

View File

@ -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 {

View File

@ -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 {

View File

@ -156,7 +156,7 @@ impl AppMachine<FetchState> {
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();

View File

@ -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!(),
};

View File

@ -182,7 +182,7 @@ impl IAppInteractSearchPrivate for AppMachine<SearchState> {
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);
}
}

View File

@ -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<ArtistMet
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,
}
@ -126,8 +128,10 @@ fn from_search_artist_response_artist(entity: SearchArtistResponseArtist) -> 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,
}

View File

@ -419,7 +419,7 @@ mod tests {
}
fn search_albums_requests() -> VecDeque<MbParams> {
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()
}

View File

@ -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},
};

View File

@ -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
),

View File

@ -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<Vec<Artist>> = 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<Vec<Artist>> = 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<Vec<Artist>> = 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<Vec<Artist>> = Lazy::new(|| -> Collection {
name: String::from("Heavens Basement"),
},
sort: Some(String::from("Heavens 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<Vec<Artist>> = 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 {