Compare commits
No commits in common. "2a32fc8ea7fcb90dbb093951f0a448f7281c766a" and "735cd00ab7cb03b65a2115e326d92568eacb068d" have entirely different histories.
2a32fc8ea7
...
735cd00ab7
@ -171,7 +171,10 @@ 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), artist_sort_value.sort)
|
||||
.set_artist_sort(
|
||||
ArtistId::new(artist_name),
|
||||
ArtistId::new(artist_sort_value.sort),
|
||||
)
|
||||
.expect("faild to set artist sort name"),
|
||||
SortCommand::Clear => music_hoard
|
||||
.clear_artist_sort(ArtistId::new(artist_name))
|
||||
|
@ -22,12 +22,6 @@ pub struct AlbumMeta {
|
||||
pub id: AlbumId,
|
||||
pub date: AlbumDate,
|
||||
pub seq: AlbumSeq,
|
||||
pub info: AlbumInfo,
|
||||
}
|
||||
|
||||
/// Album non-identifier metadata.
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct AlbumInfo {
|
||||
pub musicbrainz: MbRefOption<MbAlbumRef>,
|
||||
pub primary_type: Option<AlbumPrimaryType>,
|
||||
pub secondary_types: Vec<AlbumSecondaryType>,
|
||||
@ -150,9 +144,8 @@ impl Album {
|
||||
primary_type: Option<AlbumPrimaryType>,
|
||||
secondary_types: Vec<AlbumSecondaryType>,
|
||||
) -> Self {
|
||||
let info = AlbumInfo::new(MbRefOption::None, primary_type, secondary_types);
|
||||
Album {
|
||||
meta: AlbumMeta::new(id, date, info),
|
||||
meta: AlbumMeta::new(id, date, primary_type, secondary_types),
|
||||
tracks: vec![],
|
||||
}
|
||||
}
|
||||
@ -186,13 +179,16 @@ impl AlbumMeta {
|
||||
pub fn new<Id: Into<AlbumId>, Date: Into<AlbumDate>>(
|
||||
id: Id,
|
||||
date: Date,
|
||||
info: AlbumInfo,
|
||||
primary_type: Option<AlbumPrimaryType>,
|
||||
secondary_types: Vec<AlbumSecondaryType>,
|
||||
) -> Self {
|
||||
AlbumMeta {
|
||||
id: id.into(),
|
||||
date: date.into(),
|
||||
seq: AlbumSeq::default(),
|
||||
info,
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type,
|
||||
secondary_types,
|
||||
}
|
||||
}
|
||||
|
||||
@ -207,29 +203,29 @@ impl AlbumMeta {
|
||||
pub fn clear_seq(&mut self) {
|
||||
self.seq = AlbumSeq::default();
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for AlbumInfo {
|
||||
fn default() -> Self {
|
||||
AlbumInfo {
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type: None,
|
||||
secondary_types: Vec::new(),
|
||||
}
|
||||
pub fn set_musicbrainz_ref(&mut self, mbref: MbRefOption<MbAlbumRef>) {
|
||||
_ = mem::replace(&mut self.musicbrainz, mbref);
|
||||
}
|
||||
}
|
||||
|
||||
impl AlbumInfo {
|
||||
pub fn new(
|
||||
musicbrainz: MbRefOption<MbAlbumRef>,
|
||||
primary_type: Option<AlbumPrimaryType>,
|
||||
secondary_types: Vec<AlbumSecondaryType>,
|
||||
) -> Self {
|
||||
AlbumInfo {
|
||||
musicbrainz,
|
||||
primary_type,
|
||||
secondary_types,
|
||||
}
|
||||
pub fn clear_musicbrainz_ref(&mut self) {
|
||||
self.musicbrainz.take();
|
||||
}
|
||||
|
||||
pub fn set_primary_type(&mut self, primary_type: Option<AlbumPrimaryType>) {
|
||||
_ = mem::replace(&mut self.primary_type, primary_type);
|
||||
}
|
||||
|
||||
pub fn clear_primary_type(&mut self) {
|
||||
self.primary_type.take();
|
||||
}
|
||||
|
||||
pub fn set_secondary_types(&mut self, secondary_types: Vec<AlbumSecondaryType>) {
|
||||
self.secondary_types = secondary_types;
|
||||
}
|
||||
|
||||
pub fn clear_secondary_types(&mut self) {
|
||||
self.secondary_types.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@ -250,12 +246,6 @@ impl Merge for AlbumMeta {
|
||||
assert_eq!(self.id, other.id);
|
||||
self.seq = std::cmp::max(self.seq, other.seq);
|
||||
|
||||
self.info.merge_in_place(other.info);
|
||||
}
|
||||
}
|
||||
|
||||
impl Merge for AlbumInfo {
|
||||
fn merge_in_place(&mut self, other: Self) {
|
||||
self.musicbrainz = self.musicbrainz.take().or(other.musicbrainz);
|
||||
self.primary_type = self.primary_type.take().or(other.primary_type);
|
||||
self.secondary_types.merge_in_place(other.secondary_types);
|
||||
@ -380,4 +370,40 @@ mod tests {
|
||||
let merged = left.clone().merge(right);
|
||||
assert_eq!(expected, merged);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_clear_musicbrainz_url() {
|
||||
const MUSICBRAINZ: &str =
|
||||
"https://musicbrainz.org/release-group/c12897a3-af7a-3466-8892-58af84765813";
|
||||
const MUSICBRAINZ_2: &str =
|
||||
"https://musicbrainz.org/release-group/0eaa9306-e6df-47be-94ce-04bfe3df782c";
|
||||
|
||||
let mut album = Album::new(AlbumId::new("an album"), AlbumDate::default(), None, vec![]);
|
||||
|
||||
let mut expected: MbRefOption<MbAlbumRef> = MbRefOption::None;
|
||||
assert_eq!(album.meta.musicbrainz, expected);
|
||||
|
||||
// Setting a URL on an album.
|
||||
album.meta.set_musicbrainz_ref(MbRefOption::Some(
|
||||
MbAlbumRef::from_url_str(MUSICBRAINZ).unwrap(),
|
||||
));
|
||||
expected.replace(MbAlbumRef::from_url_str(MUSICBRAINZ).unwrap());
|
||||
assert_eq!(album.meta.musicbrainz, expected);
|
||||
|
||||
album.meta.set_musicbrainz_ref(MbRefOption::Some(
|
||||
MbAlbumRef::from_url_str(MUSICBRAINZ).unwrap(),
|
||||
));
|
||||
assert_eq!(album.meta.musicbrainz, expected);
|
||||
|
||||
album.meta.set_musicbrainz_ref(MbRefOption::Some(
|
||||
MbAlbumRef::from_url_str(MUSICBRAINZ_2).unwrap(),
|
||||
));
|
||||
expected.replace(MbAlbumRef::from_url_str(MUSICBRAINZ_2).unwrap());
|
||||
assert_eq!(album.meta.musicbrainz, expected);
|
||||
|
||||
// Clearing URLs.
|
||||
album.meta.clear_musicbrainz_ref();
|
||||
expected.take();
|
||||
assert_eq!(album.meta.musicbrainz, expected);
|
||||
}
|
||||
}
|
||||
|
@ -21,13 +21,7 @@ pub struct Artist {
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
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 sort: Option<ArtistId>,
|
||||
pub musicbrainz: MbRefOption<MbArtistRef>,
|
||||
pub properties: HashMap<String, Vec<String>>,
|
||||
}
|
||||
@ -81,36 +75,22 @@ impl ArtistMeta {
|
||||
ArtistMeta {
|
||||
id: id.into(),
|
||||
sort: None,
|
||||
info: ArtistInfo::default(),
|
||||
musicbrainz: MbRefOption::None,
|
||||
properties: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_sort_key(&self) -> (&str,) {
|
||||
(self.sort.as_ref().unwrap_or(&self.id.name),)
|
||||
pub fn get_sort_key(&self) -> (&ArtistId,) {
|
||||
(self.sort.as_ref().unwrap_or(&self.id),)
|
||||
}
|
||||
|
||||
pub fn set_sort_key<S: Into<String>>(&mut self, sort: S) {
|
||||
pub fn set_sort_key<SORT: Into<ArtistId>>(&mut self, sort: SORT) {
|
||||
self.sort = Some(sort.into());
|
||||
}
|
||||
|
||||
pub fn clear_sort_key(&mut self) {
|
||||
self.sort.take();
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ArtistInfo {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl ArtistInfo {
|
||||
pub fn new() -> Self {
|
||||
ArtistInfo {
|
||||
musicbrainz: MbRefOption::None,
|
||||
properties: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_musicbrainz_ref(&mut self, mbref: MbRefOption<MbArtistRef>) {
|
||||
self.musicbrainz = mbref
|
||||
@ -182,12 +162,6 @@ 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);
|
||||
}
|
||||
@ -233,14 +207,14 @@ mod tests {
|
||||
#[test]
|
||||
fn artist_sort_set_clear() {
|
||||
let artist_id = ArtistId::new("an artist");
|
||||
let sort_id_1 = String::from("sort id 1");
|
||||
let sort_id_2 = String::from("sort id 2");
|
||||
let sort_id_1 = ArtistId::new("sort id 1");
|
||||
let sort_id_2 = ArtistId::new("sort id 2");
|
||||
|
||||
let mut artist = Artist::new(&artist_id.name);
|
||||
|
||||
assert_eq!(artist.meta.id, artist_id);
|
||||
assert_eq!(artist.meta.sort, None);
|
||||
assert_eq!(artist.meta.get_sort_key(), (artist_id.name.as_str(),));
|
||||
assert_eq!(artist.meta.get_sort_key(), (&artist_id,));
|
||||
assert!(artist.meta < ArtistMeta::new(sort_id_1.clone()));
|
||||
assert!(artist.meta < ArtistMeta::new(sort_id_2.clone()));
|
||||
assert!(artist < Artist::new(sort_id_1.clone()));
|
||||
@ -250,7 +224,7 @@ mod tests {
|
||||
|
||||
assert_eq!(artist.meta.id, artist_id);
|
||||
assert_eq!(artist.meta.sort.as_ref(), Some(&sort_id_1));
|
||||
assert_eq!(artist.meta.get_sort_key(), (sort_id_1.as_str(),));
|
||||
assert_eq!(artist.meta.get_sort_key(), (&sort_id_1,));
|
||||
assert!(artist.meta > ArtistMeta::new(artist_id.clone()));
|
||||
assert!(artist.meta < ArtistMeta::new(sort_id_2.clone()));
|
||||
assert!(artist > Artist::new(artist_id.clone()));
|
||||
@ -260,7 +234,7 @@ mod tests {
|
||||
|
||||
assert_eq!(artist.meta.id, artist_id);
|
||||
assert_eq!(artist.meta.sort.as_ref(), Some(&sort_id_2));
|
||||
assert_eq!(artist.meta.get_sort_key(), (sort_id_2.as_str(),));
|
||||
assert_eq!(artist.meta.get_sort_key(), (&sort_id_2,));
|
||||
assert!(artist.meta > ArtistMeta::new(artist_id.clone()));
|
||||
assert!(artist.meta > ArtistMeta::new(sort_id_1.clone()));
|
||||
assert!(artist > Artist::new(artist_id.clone()));
|
||||
@ -270,7 +244,7 @@ mod tests {
|
||||
|
||||
assert_eq!(artist.meta.id, artist_id);
|
||||
assert_eq!(artist.meta.sort, None);
|
||||
assert_eq!(artist.meta.get_sort_key(), (artist_id.name.as_str(),));
|
||||
assert_eq!(artist.meta.get_sort_key(), (&artist_id,));
|
||||
assert!(artist.meta < ArtistMeta::new(sort_id_1.clone()));
|
||||
assert!(artist.meta < ArtistMeta::new(sort_id_2.clone()));
|
||||
assert!(artist < Artist::new(sort_id_1.clone()));
|
||||
@ -282,132 +256,160 @@ mod tests {
|
||||
let mut artist = Artist::new(ArtistId::new("an artist"));
|
||||
|
||||
let mut expected: MbRefOption<MbArtistRef> = MbRefOption::None;
|
||||
assert_eq!(artist.meta.info.musicbrainz, expected);
|
||||
assert_eq!(artist.meta.musicbrainz, expected);
|
||||
|
||||
// Setting a URL on an artist.
|
||||
artist.meta.info.set_musicbrainz_ref(MbRefOption::Some(
|
||||
artist.meta.set_musicbrainz_ref(MbRefOption::Some(
|
||||
MbArtistRef::from_url_str(MUSICBRAINZ).unwrap(),
|
||||
));
|
||||
expected.replace(MbArtistRef::from_url_str(MUSICBRAINZ).unwrap());
|
||||
assert_eq!(artist.meta.info.musicbrainz, expected);
|
||||
assert_eq!(artist.meta.musicbrainz, expected);
|
||||
|
||||
artist.meta.info.set_musicbrainz_ref(MbRefOption::Some(
|
||||
artist.meta.set_musicbrainz_ref(MbRefOption::Some(
|
||||
MbArtistRef::from_url_str(MUSICBRAINZ).unwrap(),
|
||||
));
|
||||
assert_eq!(artist.meta.info.musicbrainz, expected);
|
||||
assert_eq!(artist.meta.musicbrainz, expected);
|
||||
|
||||
artist.meta.info.set_musicbrainz_ref(MbRefOption::Some(
|
||||
artist.meta.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.info.musicbrainz, expected);
|
||||
assert_eq!(artist.meta.musicbrainz, expected);
|
||||
|
||||
// Clearing URLs.
|
||||
artist.meta.info.clear_musicbrainz_ref();
|
||||
artist.meta.clear_musicbrainz_ref();
|
||||
expected.take();
|
||||
assert_eq!(artist.meta.info.musicbrainz, expected);
|
||||
assert_eq!(artist.meta.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!(info.properties.is_empty());
|
||||
assert!(artist.meta.properties.is_empty());
|
||||
|
||||
// Adding a single URL.
|
||||
info.add_to_property("MusicButler", vec![MUSICBUTLER]);
|
||||
artist
|
||||
.meta
|
||||
.add_to_property("MusicButler", vec![MUSICBUTLER]);
|
||||
expected.push(MUSICBUTLER.to_owned());
|
||||
assert_eq!(info.properties.get("MusicButler"), Some(&expected));
|
||||
assert_eq!(artist.meta.properties.get("MusicButler"), Some(&expected));
|
||||
|
||||
// Adding a URL that already exists is ok, but does not do anything.
|
||||
info.add_to_property("MusicButler", vec![MUSICBUTLER]);
|
||||
assert_eq!(info.properties.get("MusicButler"), Some(&expected));
|
||||
artist
|
||||
.meta
|
||||
.add_to_property("MusicButler", vec![MUSICBUTLER]);
|
||||
assert_eq!(artist.meta.properties.get("MusicButler"), Some(&expected));
|
||||
|
||||
// Adding another single URL.
|
||||
info.add_to_property("MusicButler", vec![MUSICBUTLER_2]);
|
||||
artist
|
||||
.meta
|
||||
.add_to_property("MusicButler", vec![MUSICBUTLER_2]);
|
||||
expected.push(MUSICBUTLER_2.to_owned());
|
||||
assert_eq!(info.properties.get("MusicButler"), Some(&expected));
|
||||
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));
|
||||
artist
|
||||
.meta
|
||||
.add_to_property("MusicButler", vec![MUSICBUTLER_2]);
|
||||
assert_eq!(artist.meta.properties.get("MusicButler"), Some(&expected));
|
||||
|
||||
// Removing a URL.
|
||||
info.remove_from_property("MusicButler", vec![MUSICBUTLER]);
|
||||
artist
|
||||
.meta
|
||||
.remove_from_property("MusicButler", vec![MUSICBUTLER]);
|
||||
expected.retain(|url| url != MUSICBUTLER);
|
||||
assert_eq!(info.properties.get("MusicButler"), Some(&expected));
|
||||
assert_eq!(artist.meta.properties.get("MusicButler"), Some(&expected));
|
||||
|
||||
// Removing URls that do not exist is okay, they will be ignored.
|
||||
info.remove_from_property("MusicButler", vec![MUSICBUTLER]);
|
||||
assert_eq!(info.properties.get("MusicButler"), Some(&expected));
|
||||
artist
|
||||
.meta
|
||||
.remove_from_property("MusicButler", vec![MUSICBUTLER]);
|
||||
assert_eq!(artist.meta.properties.get("MusicButler"), Some(&expected));
|
||||
|
||||
// Removing a URL.
|
||||
info.remove_from_property("MusicButler", vec![MUSICBUTLER_2]);
|
||||
artist
|
||||
.meta
|
||||
.remove_from_property("MusicButler", vec![MUSICBUTLER_2]);
|
||||
expected.retain(|url| url.as_str() != MUSICBUTLER_2);
|
||||
assert!(info.properties.is_empty());
|
||||
assert!(artist.meta.properties.is_empty());
|
||||
|
||||
info.remove_from_property("MusicButler", vec![MUSICBUTLER_2]);
|
||||
assert!(info.properties.is_empty());
|
||||
artist
|
||||
.meta
|
||||
.remove_from_property("MusicButler", vec![MUSICBUTLER_2]);
|
||||
assert!(artist.meta.properties.is_empty());
|
||||
|
||||
// Adding URLs if some exist is okay, they will be ignored.
|
||||
info.add_to_property("MusicButler", vec![MUSICBUTLER]);
|
||||
artist
|
||||
.meta
|
||||
.add_to_property("MusicButler", vec![MUSICBUTLER]);
|
||||
expected.push(MUSICBUTLER.to_owned());
|
||||
assert_eq!(info.properties.get("MusicButler"), Some(&expected));
|
||||
assert_eq!(artist.meta.properties.get("MusicButler"), Some(&expected));
|
||||
|
||||
info.add_to_property("MusicButler", vec![MUSICBUTLER, MUSICBUTLER_2]);
|
||||
artist
|
||||
.meta
|
||||
.add_to_property("MusicButler", vec![MUSICBUTLER, MUSICBUTLER_2]);
|
||||
expected.push(MUSICBUTLER_2.to_owned());
|
||||
assert_eq!(info.properties.get("MusicButler"), Some(&expected));
|
||||
assert_eq!(artist.meta.properties.get("MusicButler"), Some(&expected));
|
||||
|
||||
// Removing URLs if some do not exist is okay, they will be ignored.
|
||||
info.remove_from_property("MusicButler", vec![MUSICBUTLER]);
|
||||
artist
|
||||
.meta
|
||||
.remove_from_property("MusicButler", vec![MUSICBUTLER]);
|
||||
expected.retain(|url| url.as_str() != MUSICBUTLER);
|
||||
assert_eq!(info.properties.get("MusicButler"), Some(&expected));
|
||||
assert_eq!(artist.meta.properties.get("MusicButler"), Some(&expected));
|
||||
|
||||
info.remove_from_property("MusicButler", vec![MUSICBUTLER, MUSICBUTLER_2]);
|
||||
artist
|
||||
.meta
|
||||
.remove_from_property("MusicButler", vec![MUSICBUTLER, MUSICBUTLER_2]);
|
||||
expected.retain(|url| url.as_str() != MUSICBUTLER_2);
|
||||
assert!(info.properties.is_empty());
|
||||
assert!(artist.meta.properties.is_empty());
|
||||
|
||||
// Adding mutliple URLs without clashes.
|
||||
info.add_to_property("MusicButler", vec![MUSICBUTLER, MUSICBUTLER_2]);
|
||||
artist
|
||||
.meta
|
||||
.add_to_property("MusicButler", vec![MUSICBUTLER, MUSICBUTLER_2]);
|
||||
expected.push(MUSICBUTLER.to_owned());
|
||||
expected.push(MUSICBUTLER_2.to_owned());
|
||||
assert_eq!(info.properties.get("MusicButler"), Some(&expected));
|
||||
assert_eq!(artist.meta.properties.get("MusicButler"), Some(&expected));
|
||||
|
||||
// Removing multiple URLs without clashes.
|
||||
info.remove_from_property("MusicButler", vec![MUSICBUTLER, MUSICBUTLER_2]);
|
||||
artist
|
||||
.meta
|
||||
.remove_from_property("MusicButler", vec![MUSICBUTLER, MUSICBUTLER_2]);
|
||||
expected.clear();
|
||||
assert!(info.properties.is_empty());
|
||||
assert!(artist.meta.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!(info.properties.is_empty());
|
||||
assert!(artist.meta.properties.is_empty());
|
||||
|
||||
// Set URLs.
|
||||
info.set_property("MusicButler", vec![MUSICBUTLER]);
|
||||
artist.meta.set_property("MusicButler", vec![MUSICBUTLER]);
|
||||
expected.push(MUSICBUTLER.to_owned());
|
||||
assert_eq!(info.properties.get("MusicButler"), Some(&expected));
|
||||
assert_eq!(artist.meta.properties.get("MusicButler"), Some(&expected));
|
||||
|
||||
info.set_property("MusicButler", vec![MUSICBUTLER_2]);
|
||||
artist.meta.set_property("MusicButler", vec![MUSICBUTLER_2]);
|
||||
expected.clear();
|
||||
expected.push(MUSICBUTLER_2.to_owned());
|
||||
assert_eq!(info.properties.get("MusicButler"), Some(&expected));
|
||||
assert_eq!(artist.meta.properties.get("MusicButler"), Some(&expected));
|
||||
|
||||
info.set_property("MusicButler", vec![MUSICBUTLER, MUSICBUTLER_2]);
|
||||
artist
|
||||
.meta
|
||||
.set_property("MusicButler", vec![MUSICBUTLER, MUSICBUTLER_2]);
|
||||
expected.clear();
|
||||
expected.push(MUSICBUTLER.to_owned());
|
||||
expected.push(MUSICBUTLER_2.to_owned());
|
||||
assert_eq!(info.properties.get("MusicButler"), Some(&expected));
|
||||
assert_eq!(artist.meta.properties.get("MusicButler"), Some(&expected));
|
||||
|
||||
// Clear URLs.
|
||||
info.clear_property("MusicButler");
|
||||
artist.meta.clear_property("MusicButler");
|
||||
expected.clear();
|
||||
assert!(info.properties.is_empty());
|
||||
assert!(artist.meta.properties.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -415,15 +417,14 @@ 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.info.musicbrainz = MbRefOption::None;
|
||||
right.meta.info.properties = HashMap::new();
|
||||
right.meta.musicbrainz = MbRefOption::None;
|
||||
right.meta.properties = HashMap::new();
|
||||
|
||||
let mut expected = left.clone();
|
||||
expected.meta.info.properties = expected
|
||||
expected.meta.properties = expected
|
||||
.meta
|
||||
.info
|
||||
.properties
|
||||
.merge(right.clone().meta.info.properties);
|
||||
.merge(right.clone().meta.properties);
|
||||
expected.albums.append(&mut right.albums.clone());
|
||||
expected.albums.sort_unstable();
|
||||
|
||||
@ -444,11 +445,10 @@ mod tests {
|
||||
left.albums.sort_unstable();
|
||||
|
||||
let mut expected = left.clone();
|
||||
expected.meta.info.properties = expected
|
||||
expected.meta.properties = expected
|
||||
.meta
|
||||
.info
|
||||
.properties
|
||||
.merge(right.clone().meta.info.properties);
|
||||
.merge(right.clone().meta.properties);
|
||||
expected.albums.append(&mut right.albums.clone());
|
||||
expected.albums.sort_unstable();
|
||||
expected.albums.dedup();
|
||||
|
@ -97,7 +97,7 @@ impl<Database, Library> IMusicHoardBasePrivate for MusicHoard<Database, Library>
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::core::testmod::FULL_COLLECTION;
|
||||
use crate::core::{collection::artist::ArtistId, testmod::FULL_COLLECTION};
|
||||
|
||||
use super::*;
|
||||
|
||||
@ -190,7 +190,7 @@ mod tests {
|
||||
let mut right: Vec<Artist> = vec![left.last().unwrap().clone()];
|
||||
|
||||
assert!(right.first().unwrap() > left.first().unwrap());
|
||||
let artist_sort = Some(String::from("Album_Artist 0"));
|
||||
let artist_sort = Some(ArtistId::new("Album_Artist 0"));
|
||||
right[0].meta.sort = artist_sort.clone();
|
||||
assert!(right.first().unwrap() < left.first().unwrap());
|
||||
|
||||
|
@ -1,9 +1,13 @@
|
||||
use crate::{
|
||||
collection::{album::AlbumInfo, artist::ArtistInfo},
|
||||
collection::{
|
||||
album::{AlbumPrimaryType, AlbumSecondaryType},
|
||||
musicbrainz::{MbAlbumRef, MbRefOption},
|
||||
},
|
||||
core::{
|
||||
collection::{
|
||||
album::{Album, AlbumId, AlbumSeq},
|
||||
artist::{Artist, ArtistId},
|
||||
musicbrainz::MbArtistRef,
|
||||
Collection,
|
||||
},
|
||||
interface::database::IDatabase,
|
||||
@ -17,19 +21,20 @@ pub trait IMusicHoardDatabase {
|
||||
fn add_artist<IntoId: Into<ArtistId>>(&mut self, artist_id: IntoId) -> Result<(), Error>;
|
||||
fn remove_artist<Id: AsRef<ArtistId>>(&mut self, artist_id: Id) -> Result<(), Error>;
|
||||
|
||||
fn set_artist_sort<Id: AsRef<ArtistId>, S: Into<String>>(
|
||||
fn set_artist_sort<Id: AsRef<ArtistId>, IntoId: Into<ArtistId>>(
|
||||
&mut self,
|
||||
artist_id: Id,
|
||||
artist_sort: S,
|
||||
artist_sort: IntoId,
|
||||
) -> Result<(), Error>;
|
||||
fn clear_artist_sort<Id: AsRef<ArtistId>>(&mut self, artist_id: Id) -> Result<(), Error>;
|
||||
|
||||
fn set_artist_info<Id: AsRef<ArtistId>>(
|
||||
fn set_artist_musicbrainz<Id: AsRef<ArtistId>>(
|
||||
&mut self,
|
||||
artist_id: Id,
|
||||
info: ArtistInfo,
|
||||
mbid: MbRefOption<MbArtistRef>,
|
||||
) -> Result<(), Error>;
|
||||
fn clear_artist_info<Id: AsRef<ArtistId>>(&mut self, artist_id: Id) -> Result<(), Error>;
|
||||
fn clear_artist_musicbrainz<Id: AsRef<ArtistId>>(&mut self, artist_id: Id)
|
||||
-> Result<(), Error>;
|
||||
|
||||
fn add_to_artist_property<Id: AsRef<ArtistId>, S: AsRef<str> + Into<String>>(
|
||||
&mut self,
|
||||
@ -55,6 +60,17 @@ pub trait IMusicHoardDatabase {
|
||||
property: S,
|
||||
) -> Result<(), Error>;
|
||||
|
||||
fn set_album_musicbrainz<Id: AsRef<ArtistId>, AlbumIdRef: AsRef<AlbumId>>(
|
||||
&mut self,
|
||||
artist_id: Id,
|
||||
album_id: AlbumIdRef,
|
||||
mbid: MbRefOption<MbAlbumRef>,
|
||||
) -> Result<(), Error>;
|
||||
fn clear_album_musicbrainz<Id: AsRef<ArtistId>, AlbumIdRef: AsRef<AlbumId>>(
|
||||
&mut self,
|
||||
artist_id: Id,
|
||||
album_id: AlbumIdRef,
|
||||
) -> Result<(), Error>;
|
||||
fn set_album_seq<ArtistIdRef: AsRef<ArtistId>, AlbumIdRef: AsRef<AlbumId>>(
|
||||
&mut self,
|
||||
artist_id: ArtistIdRef,
|
||||
@ -66,13 +82,24 @@ pub trait IMusicHoardDatabase {
|
||||
artist_id: ArtistIdRef,
|
||||
album_id: AlbumIdRef,
|
||||
) -> Result<(), Error>;
|
||||
fn set_album_info<Id: AsRef<ArtistId>, AlbumIdRef: AsRef<AlbumId>>(
|
||||
fn set_album_primary_type<Id: AsRef<ArtistId>, AlbumIdRef: AsRef<AlbumId>>(
|
||||
&mut self,
|
||||
artist_id: Id,
|
||||
album_id: AlbumIdRef,
|
||||
info: AlbumInfo,
|
||||
primary_type: Option<AlbumPrimaryType>,
|
||||
) -> Result<(), Error>;
|
||||
fn clear_album_info<Id: AsRef<ArtistId>, AlbumIdRef: AsRef<AlbumId>>(
|
||||
fn clear_album_primary_type<Id: AsRef<ArtistId>, AlbumIdRef: AsRef<AlbumId>>(
|
||||
&mut self,
|
||||
artist_id: Id,
|
||||
album_id: AlbumIdRef,
|
||||
) -> Result<(), Error>;
|
||||
fn set_album_secondary_types<Id: AsRef<ArtistId>, AlbumIdRef: AsRef<AlbumId>>(
|
||||
&mut self,
|
||||
artist_id: Id,
|
||||
album_id: AlbumIdRef,
|
||||
secondary_types: Vec<AlbumSecondaryType>,
|
||||
) -> Result<(), Error>;
|
||||
fn clear_album_secondary_types<Id: AsRef<ArtistId>, AlbumIdRef: AsRef<AlbumId>>(
|
||||
&mut self,
|
||||
artist_id: Id,
|
||||
album_id: AlbumIdRef,
|
||||
@ -112,10 +139,10 @@ impl<Database: IDatabase, Library> IMusicHoardDatabase for MusicHoard<Database,
|
||||
})
|
||||
}
|
||||
|
||||
fn set_artist_sort<Id: AsRef<ArtistId>, S: Into<String>>(
|
||||
fn set_artist_sort<Id: AsRef<ArtistId>, IntoId: Into<ArtistId>>(
|
||||
&mut self,
|
||||
artist_id: Id,
|
||||
artist_sort: S,
|
||||
artist_sort: IntoId,
|
||||
) -> Result<(), Error> {
|
||||
self.update_artist_and(
|
||||
artist_id.as_ref(),
|
||||
@ -132,17 +159,22 @@ impl<Database: IDatabase, Library> IMusicHoardDatabase for MusicHoard<Database,
|
||||
)
|
||||
}
|
||||
|
||||
fn set_artist_info<Id: AsRef<ArtistId>>(
|
||||
fn set_artist_musicbrainz<Id: AsRef<ArtistId>>(
|
||||
&mut self,
|
||||
artist_id: Id,
|
||||
info: ArtistInfo,
|
||||
mbid: MbRefOption<MbArtistRef>,
|
||||
) -> Result<(), Error> {
|
||||
self.update_artist(artist_id.as_ref(), |artist| artist.meta.info = info)
|
||||
self.update_artist(artist_id.as_ref(), |artist| {
|
||||
artist.meta.set_musicbrainz_ref(mbid)
|
||||
})
|
||||
}
|
||||
|
||||
fn clear_artist_info<Id: AsRef<ArtistId>>(&mut self, artist_id: Id) -> Result<(), Error> {
|
||||
fn clear_artist_musicbrainz<Id: AsRef<ArtistId>>(
|
||||
&mut self,
|
||||
artist_id: Id,
|
||||
) -> Result<(), Error> {
|
||||
self.update_artist(artist_id.as_ref(), |artist| {
|
||||
artist.meta.info = ArtistInfo::default()
|
||||
artist.meta.clear_musicbrainz_ref()
|
||||
})
|
||||
}
|
||||
|
||||
@ -153,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.info.add_to_property(property, values)
|
||||
artist.meta.add_to_property(property, values)
|
||||
})
|
||||
}
|
||||
|
||||
@ -164,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.info.remove_from_property(property, values)
|
||||
artist.meta.remove_from_property(property, values)
|
||||
})
|
||||
}
|
||||
|
||||
@ -175,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.info.set_property(property, values)
|
||||
artist.meta.set_property(property, values)
|
||||
})
|
||||
}
|
||||
|
||||
@ -185,7 +217,28 @@ impl<Database: IDatabase, Library> IMusicHoardDatabase for MusicHoard<Database,
|
||||
property: S,
|
||||
) -> Result<(), Error> {
|
||||
self.update_artist(artist_id.as_ref(), |artist| {
|
||||
artist.meta.info.clear_property(property)
|
||||
artist.meta.clear_property(property)
|
||||
})
|
||||
}
|
||||
|
||||
fn set_album_musicbrainz<Id: AsRef<ArtistId>, AlbumIdRef: AsRef<AlbumId>>(
|
||||
&mut self,
|
||||
artist_id: Id,
|
||||
album_id: AlbumIdRef,
|
||||
mbid: MbRefOption<MbAlbumRef>,
|
||||
) -> Result<(), Error> {
|
||||
self.update_album(artist_id.as_ref(), album_id.as_ref(), |album| {
|
||||
album.meta.set_musicbrainz_ref(mbid)
|
||||
})
|
||||
}
|
||||
|
||||
fn clear_album_musicbrainz<Id: AsRef<ArtistId>, AlbumIdRef: AsRef<AlbumId>>(
|
||||
&mut self,
|
||||
artist_id: Id,
|
||||
album_id: AlbumIdRef,
|
||||
) -> Result<(), Error> {
|
||||
self.update_album(artist_id.as_ref(), album_id.as_ref(), |album| {
|
||||
album.meta.clear_musicbrainz_ref()
|
||||
})
|
||||
}
|
||||
|
||||
@ -216,24 +269,45 @@ impl<Database: IDatabase, Library> IMusicHoardDatabase for MusicHoard<Database,
|
||||
)
|
||||
}
|
||||
|
||||
fn set_album_info<Id: AsRef<ArtistId>, AlbumIdRef: AsRef<AlbumId>>(
|
||||
fn set_album_primary_type<Id: AsRef<ArtistId>, AlbumIdRef: AsRef<AlbumId>>(
|
||||
&mut self,
|
||||
artist_id: Id,
|
||||
album_id: AlbumIdRef,
|
||||
info: AlbumInfo,
|
||||
primary_type: Option<AlbumPrimaryType>,
|
||||
) -> Result<(), Error> {
|
||||
self.update_album(artist_id.as_ref(), album_id.as_ref(), |album| {
|
||||
album.meta.info = info
|
||||
album.meta.set_primary_type(primary_type)
|
||||
})
|
||||
}
|
||||
|
||||
fn clear_album_info<Id: AsRef<ArtistId>, AlbumIdRef: AsRef<AlbumId>>(
|
||||
fn clear_album_primary_type<Id: AsRef<ArtistId>, AlbumIdRef: AsRef<AlbumId>>(
|
||||
&mut self,
|
||||
artist_id: Id,
|
||||
album_id: AlbumIdRef,
|
||||
) -> Result<(), Error> {
|
||||
self.update_album(artist_id.as_ref(), album_id.as_ref(), |album| {
|
||||
album.meta.info = AlbumInfo::default()
|
||||
album.meta.clear_primary_type()
|
||||
})
|
||||
}
|
||||
|
||||
fn set_album_secondary_types<Id: AsRef<ArtistId>, AlbumIdRef: AsRef<AlbumId>>(
|
||||
&mut self,
|
||||
artist_id: Id,
|
||||
album_id: AlbumIdRef,
|
||||
secondary_types: Vec<AlbumSecondaryType>,
|
||||
) -> Result<(), Error> {
|
||||
self.update_album(artist_id.as_ref(), album_id.as_ref(), |album| {
|
||||
album.meta.set_secondary_types(secondary_types)
|
||||
})
|
||||
}
|
||||
|
||||
fn clear_album_secondary_types<Id: AsRef<ArtistId>, AlbumIdRef: AsRef<AlbumId>>(
|
||||
&mut self,
|
||||
artist_id: Id,
|
||||
album_id: AlbumIdRef,
|
||||
) -> Result<(), Error> {
|
||||
self.update_album(artist_id.as_ref(), album_id.as_ref(), |album| {
|
||||
album.meta.clear_secondary_types()
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -333,7 +407,7 @@ mod tests {
|
||||
use mockall::{predicate, Sequence};
|
||||
|
||||
use crate::{
|
||||
collection::musicbrainz::{MbArtistRef, MbRefOption},
|
||||
collection::musicbrainz::MbRefOption,
|
||||
core::{
|
||||
collection::{album::AlbumDate, artist::ArtistId},
|
||||
interface::database::{self, MockIDatabase},
|
||||
@ -404,12 +478,12 @@ mod tests {
|
||||
let mut music_hoard: MH = MusicHoard::database(database).unwrap();
|
||||
|
||||
let artist_1_id = ArtistId::new("the artist");
|
||||
let artist_1_sort = String::from("artist, the");
|
||||
let artist_1_sort = ArtistId::new("artist, the");
|
||||
|
||||
// Must be after "artist, the", but before "the artist"
|
||||
let artist_2_id = ArtistId::new("b-artist");
|
||||
|
||||
assert!(artist_1_sort < artist_2_id.name);
|
||||
assert!(artist_1_sort < artist_2_id);
|
||||
assert!(artist_2_id < artist_1_id);
|
||||
|
||||
assert!(music_hoard.add_artist(artist_1_id.clone()).is_ok());
|
||||
@ -447,7 +521,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_clear_info() {
|
||||
fn set_clear_musicbrainz_url() {
|
||||
let mut database = MockIDatabase::new();
|
||||
database.expect_load().times(1).returning(|| Ok(vec![]));
|
||||
database.expect_save().times(3).returning(|_| Ok(()));
|
||||
@ -459,32 +533,31 @@ 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.info.musicbrainz, expected);
|
||||
assert_eq!(music_hoard.collection[0].meta.musicbrainz, expected);
|
||||
|
||||
let mut info = ArtistInfo::new();
|
||||
info.musicbrainz = MbRefOption::Some(MbArtistRef::from_uuid_str(MBID).unwrap());
|
||||
let mbref = MbRefOption::Some(MbArtistRef::from_uuid_str(MBID).unwrap());
|
||||
|
||||
// Setting a URL on an artist not in the collection is an error.
|
||||
assert!(music_hoard
|
||||
.set_artist_info(&artist_id_2, info.clone())
|
||||
.set_artist_musicbrainz(&artist_id_2, mbref.clone())
|
||||
.is_err());
|
||||
assert_eq!(music_hoard.collection[0].meta.info.musicbrainz, expected);
|
||||
assert_eq!(music_hoard.collection[0].meta.musicbrainz, expected);
|
||||
|
||||
// Setting a URL on an artist.
|
||||
assert!(music_hoard
|
||||
.set_artist_info(&artist_id, info.clone())
|
||||
.set_artist_musicbrainz(&artist_id, mbref.clone())
|
||||
.is_ok());
|
||||
expected.replace(MbArtistRef::from_uuid_str(MBID).unwrap());
|
||||
assert_eq!(music_hoard.collection[0].meta.info.musicbrainz, expected);
|
||||
assert_eq!(music_hoard.collection[0].meta.musicbrainz, expected);
|
||||
|
||||
// Clearing URLs on an artist that does not exist is an error.
|
||||
assert!(music_hoard.clear_artist_info(&artist_id_2).is_err());
|
||||
assert_eq!(music_hoard.collection[0].meta.info.musicbrainz, expected);
|
||||
assert!(music_hoard.clear_artist_musicbrainz(&artist_id_2).is_err());
|
||||
assert_eq!(music_hoard.collection[0].meta.musicbrainz, expected);
|
||||
|
||||
// Clearing URLs.
|
||||
assert!(music_hoard.clear_artist_info(&artist_id).is_ok());
|
||||
assert!(music_hoard.clear_artist_musicbrainz(&artist_id).is_ok());
|
||||
expected.take();
|
||||
assert_eq!(music_hoard.collection[0].meta.info.musicbrainz, expected);
|
||||
assert_eq!(music_hoard.collection[0].meta.musicbrainz, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -500,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.info.properties.is_empty());
|
||||
assert!(music_hoard.collection[0].meta.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.info.properties.is_empty());
|
||||
assert!(music_hoard.collection[0].meta.properties.is_empty());
|
||||
|
||||
// Adding mutliple URLs without clashes.
|
||||
assert!(music_hoard
|
||||
@ -514,15 +587,19 @@ mod tests {
|
||||
.is_ok());
|
||||
expected.push(MUSICBUTLER.to_owned());
|
||||
expected.push(MUSICBUTLER_2.to_owned());
|
||||
let info = &music_hoard.collection[0].meta.info;
|
||||
assert_eq!(info.properties.get("MusicButler"), Some(&expected));
|
||||
assert_eq!(
|
||||
music_hoard.collection[0].meta.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());
|
||||
let info = &music_hoard.collection[0].meta.info;
|
||||
assert_eq!(info.properties.get("MusicButler"), Some(&expected));
|
||||
assert_eq!(
|
||||
music_hoard.collection[0].meta.properties.get("MusicButler"),
|
||||
Some(&expected)
|
||||
);
|
||||
|
||||
// Removing multiple URLs without clashes.
|
||||
assert!(music_hoard
|
||||
@ -533,7 +610,7 @@ mod tests {
|
||||
)
|
||||
.is_ok());
|
||||
expected.clear();
|
||||
assert!(music_hoard.collection[0].meta.info.properties.is_empty());
|
||||
assert!(music_hoard.collection[0].meta.properties.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -549,13 +626,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.info.properties.is_empty());
|
||||
assert!(music_hoard.collection[0].meta.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.info.properties.is_empty());
|
||||
assert!(music_hoard.collection[0].meta.properties.is_empty());
|
||||
|
||||
// Set URLs.
|
||||
assert!(music_hoard
|
||||
@ -564,8 +641,10 @@ mod tests {
|
||||
expected.clear();
|
||||
expected.push(MUSICBUTLER.to_owned());
|
||||
expected.push(MUSICBUTLER_2.to_owned());
|
||||
let info = &music_hoard.collection[0].meta.info;
|
||||
assert_eq!(info.properties.get("MusicButler"), Some(&expected));
|
||||
assert_eq!(
|
||||
music_hoard.collection[0].meta.properties.get("MusicButler"),
|
||||
Some(&expected)
|
||||
);
|
||||
|
||||
// Clearing URLs on an artist that does not exist is an error.
|
||||
assert!(music_hoard
|
||||
@ -577,7 +656,7 @@ mod tests {
|
||||
.clear_artist_property(&artist_id, "MusicButler")
|
||||
.is_ok());
|
||||
expected.clear();
|
||||
assert!(music_hoard.collection[0].meta.info.properties.is_empty());
|
||||
assert!(music_hoard.collection[0].meta.properties.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -52,7 +52,7 @@ impl<Database, Library: ILibrary> MusicHoard<Database, Library> {
|
||||
name: item.album_artist,
|
||||
};
|
||||
|
||||
let artist_sort = item.album_artist_sort;
|
||||
let artist_sort = item.album_artist_sort.map(|s| ArtistId { name: s });
|
||||
|
||||
let album_id = AlbumId {
|
||||
title: item.album_title,
|
||||
|
@ -2,8 +2,8 @@ use once_cell::sync::Lazy;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::core::collection::{
|
||||
album::{Album, AlbumId, AlbumInfo, AlbumMeta, AlbumPrimaryType, AlbumSeq},
|
||||
artist::{Artist, ArtistId, ArtistInfo, ArtistMeta},
|
||||
album::{Album, AlbumId, AlbumMeta, AlbumPrimaryType, AlbumSeq},
|
||||
artist::{Artist, ArtistId, ArtistMeta},
|
||||
musicbrainz::{MbAlbumRef, MbArtistRef, MbRefOption},
|
||||
track::{Track, TrackFormat, TrackId, TrackNum, TrackQuality},
|
||||
};
|
||||
|
20
src/external/database/serde/deserialize.rs
vendored
20
src/external/database/serde/deserialize.rs
vendored
@ -4,8 +4,8 @@ use serde::{de::Visitor, Deserialize, Deserializer};
|
||||
|
||||
use crate::{
|
||||
collection::{
|
||||
album::{AlbumInfo, AlbumMeta},
|
||||
artist::{ArtistInfo, ArtistMeta},
|
||||
album::AlbumMeta,
|
||||
artist::ArtistMeta,
|
||||
musicbrainz::{MbAlbumRef, MbArtistRef, MbRefOption, Mbid},
|
||||
},
|
||||
core::collection::{
|
||||
@ -114,11 +114,9 @@ impl From<DeserializeArtist> for Artist {
|
||||
Artist {
|
||||
meta: ArtistMeta {
|
||||
id: ArtistId::new(artist.name),
|
||||
sort: artist.sort,
|
||||
info: ArtistInfo {
|
||||
musicbrainz: artist.musicbrainz.into(),
|
||||
properties: artist.properties,
|
||||
},
|
||||
sort: artist.sort.map(ArtistId::new),
|
||||
musicbrainz: artist.musicbrainz.into(),
|
||||
properties: artist.properties,
|
||||
},
|
||||
albums: artist.albums.into_iter().map(Into::into).collect(),
|
||||
}
|
||||
@ -132,11 +130,9 @@ impl From<DeserializeAlbum> for Album {
|
||||
id: AlbumId { title: album.title },
|
||||
date: AlbumDate::default(),
|
||||
seq: AlbumSeq(album.seq),
|
||||
info: AlbumInfo {
|
||||
musicbrainz: album.musicbrainz.into(),
|
||||
primary_type: album.primary_type.map(Into::into),
|
||||
secondary_types: album.secondary_types.into_iter().map(Into::into).collect(),
|
||||
},
|
||||
musicbrainz: album.musicbrainz.into(),
|
||||
primary_type: album.primary_type.map(Into::into),
|
||||
secondary_types: album.secondary_types.into_iter().map(Into::into).collect(),
|
||||
},
|
||||
tracks: vec![],
|
||||
}
|
||||
|
10
src/external/database/serde/serialize.rs
vendored
10
src/external/database/serde/serialize.rs
vendored
@ -72,11 +72,10 @@ impl<'a> From<&'a Artist> for SerializeArtist<'a> {
|
||||
fn from(artist: &'a Artist) -> Self {
|
||||
SerializeArtist {
|
||||
name: &artist.meta.id.name,
|
||||
sort: artist.meta.sort.as_deref(),
|
||||
musicbrainz: (&artist.meta.info.musicbrainz).into(),
|
||||
sort: artist.meta.sort.as_ref().map(|id| id.name.as_ref()),
|
||||
musicbrainz: (&artist.meta.musicbrainz).into(),
|
||||
properties: artist
|
||||
.meta
|
||||
.info
|
||||
.properties
|
||||
.iter()
|
||||
.map(|(k, v)| (k.as_ref(), v))
|
||||
@ -91,11 +90,10 @@ impl<'a> From<&'a Album> for SerializeAlbum<'a> {
|
||||
SerializeAlbum {
|
||||
title: &album.meta.id.title,
|
||||
seq: album.meta.seq.0,
|
||||
musicbrainz: (&album.meta.info.musicbrainz).into(),
|
||||
primary_type: album.meta.info.primary_type.map(Into::into),
|
||||
musicbrainz: (&album.meta.musicbrainz).into(),
|
||||
primary_type: album.meta.primary_type.map(Into::into),
|
||||
secondary_types: album
|
||||
.meta
|
||||
.info
|
||||
.secondary_types
|
||||
.iter()
|
||||
.copied()
|
||||
|
15
src/external/musicbrainz/api/mod.rs
vendored
15
src/external/musicbrainz/api/mod.rs
vendored
@ -4,7 +4,8 @@ use serde::{de::Visitor, Deserialize, Deserializer};
|
||||
|
||||
use crate::{
|
||||
collection::{
|
||||
album::{AlbumDate, AlbumPrimaryType, AlbumSecondaryType},
|
||||
album::{AlbumDate, AlbumId, AlbumPrimaryType, AlbumSecondaryType},
|
||||
artist::ArtistId,
|
||||
musicbrainz::Mbid,
|
||||
Error as CollectionError,
|
||||
},
|
||||
@ -61,8 +62,8 @@ impl<Http> MusicBrainzClient<Http> {
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct MbArtistMeta {
|
||||
pub id: Mbid,
|
||||
pub name: String,
|
||||
pub sort_name: String,
|
||||
pub name: ArtistId,
|
||||
pub sort_name: ArtistId,
|
||||
pub disambiguation: Option<String>,
|
||||
}
|
||||
|
||||
@ -79,8 +80,8 @@ impl From<SerdeMbArtistMeta> for MbArtistMeta {
|
||||
fn from(value: SerdeMbArtistMeta) -> Self {
|
||||
MbArtistMeta {
|
||||
id: value.id.into(),
|
||||
name: value.name,
|
||||
sort_name: value.sort_name,
|
||||
name: value.name.into(),
|
||||
sort_name: value.sort_name.into(),
|
||||
disambiguation: value.disambiguation,
|
||||
}
|
||||
}
|
||||
@ -89,7 +90,7 @@ impl From<SerdeMbArtistMeta> for MbArtistMeta {
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct MbReleaseGroupMeta {
|
||||
pub id: Mbid,
|
||||
pub title: String,
|
||||
pub title: AlbumId,
|
||||
pub first_release_date: AlbumDate,
|
||||
pub primary_type: AlbumPrimaryType,
|
||||
pub secondary_types: Option<Vec<AlbumSecondaryType>>,
|
||||
@ -109,7 +110,7 @@ impl From<SerdeMbReleaseGroupMeta> for MbReleaseGroupMeta {
|
||||
fn from(value: SerdeMbReleaseGroupMeta) -> Self {
|
||||
MbReleaseGroupMeta {
|
||||
id: value.id.into(),
|
||||
title: value.title,
|
||||
title: value.title.into(),
|
||||
first_release_date: value.first_release_date.into(),
|
||||
primary_type: value.primary_type.into(),
|
||||
secondary_types: value
|
||||
|
@ -7,21 +7,19 @@ macro_rules! full_collection {
|
||||
name: "Album_Artist ‘A’".to_string(),
|
||||
},
|
||||
sort: None,
|
||||
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",
|
||||
)
|
||||
]),
|
||||
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",
|
||||
)
|
||||
]),
|
||||
]),
|
||||
},
|
||||
albums: vec![
|
||||
Album {
|
||||
@ -31,13 +29,11 @@ macro_rules! full_collection {
|
||||
},
|
||||
date: 1998.into(),
|
||||
seq: AlbumSeq(1),
|
||||
info: AlbumInfo {
|
||||
musicbrainz: MbRefOption::Some(MbAlbumRef::from_url_str(
|
||||
"https://musicbrainz.org/release-group/00000000-0000-0000-0000-000000000000"
|
||||
).unwrap()),
|
||||
primary_type: Some(AlbumPrimaryType::Album),
|
||||
secondary_types: vec![],
|
||||
},
|
||||
musicbrainz: MbRefOption::Some(MbAlbumRef::from_url_str(
|
||||
"https://musicbrainz.org/release-group/00000000-0000-0000-0000-000000000000"
|
||||
).unwrap()),
|
||||
primary_type: Some(AlbumPrimaryType::Album),
|
||||
secondary_types: vec![],
|
||||
},
|
||||
tracks: vec![
|
||||
Track {
|
||||
@ -96,11 +92,9 @@ macro_rules! full_collection {
|
||||
},
|
||||
date: (2015, 4).into(),
|
||||
seq: AlbumSeq(1),
|
||||
info: AlbumInfo {
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type: Some(AlbumPrimaryType::Album),
|
||||
secondary_types: vec![],
|
||||
},
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type: Some(AlbumPrimaryType::Album),
|
||||
secondary_types: vec![],
|
||||
},
|
||||
tracks: vec![
|
||||
Track {
|
||||
@ -135,25 +129,23 @@ macro_rules! full_collection {
|
||||
name: "Album_Artist ‘B’".to_string(),
|
||||
},
|
||||
sort: None,
|
||||
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",
|
||||
)
|
||||
]),
|
||||
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",
|
||||
)
|
||||
]),
|
||||
]),
|
||||
},
|
||||
albums: vec![
|
||||
Album {
|
||||
@ -163,11 +155,9 @@ macro_rules! full_collection {
|
||||
},
|
||||
date: (2003, 6, 6).into(),
|
||||
seq: AlbumSeq(1),
|
||||
info: AlbumInfo {
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type: Some(AlbumPrimaryType::Album),
|
||||
secondary_types: vec![],
|
||||
},
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type: Some(AlbumPrimaryType::Album),
|
||||
secondary_types: vec![],
|
||||
},
|
||||
tracks: vec![
|
||||
Track {
|
||||
@ -204,13 +194,11 @@ macro_rules! full_collection {
|
||||
},
|
||||
date: 2008.into(),
|
||||
seq: AlbumSeq(3),
|
||||
info: AlbumInfo {
|
||||
musicbrainz: MbRefOption::Some(MbAlbumRef::from_url_str(
|
||||
"https://musicbrainz.org/release-group/11111111-1111-1111-1111-111111111111"
|
||||
).unwrap()),
|
||||
primary_type: Some(AlbumPrimaryType::Album),
|
||||
secondary_types: vec![],
|
||||
},
|
||||
musicbrainz: MbRefOption::Some(MbAlbumRef::from_url_str(
|
||||
"https://musicbrainz.org/release-group/11111111-1111-1111-1111-111111111111"
|
||||
).unwrap()),
|
||||
primary_type: Some(AlbumPrimaryType::Album),
|
||||
secondary_types: vec![],
|
||||
},
|
||||
tracks: vec![
|
||||
Track {
|
||||
@ -247,13 +235,11 @@ macro_rules! full_collection {
|
||||
},
|
||||
date: 2009.into(),
|
||||
seq: AlbumSeq(2),
|
||||
info: AlbumInfo {
|
||||
musicbrainz: MbRefOption::Some(MbAlbumRef::from_url_str(
|
||||
"https://musicbrainz.org/release-group/11111111-1111-1111-1111-111111111112"
|
||||
).unwrap()),
|
||||
primary_type: Some(AlbumPrimaryType::Album),
|
||||
secondary_types: vec![],
|
||||
},
|
||||
musicbrainz: MbRefOption::Some(MbAlbumRef::from_url_str(
|
||||
"https://musicbrainz.org/release-group/11111111-1111-1111-1111-111111111112"
|
||||
).unwrap()),
|
||||
primary_type: Some(AlbumPrimaryType::Album),
|
||||
secondary_types: vec![],
|
||||
},
|
||||
tracks: vec![
|
||||
Track {
|
||||
@ -290,11 +276,9 @@ macro_rules! full_collection {
|
||||
},
|
||||
date: 2015.into(),
|
||||
seq: AlbumSeq(4),
|
||||
info: AlbumInfo {
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type: Some(AlbumPrimaryType::Album),
|
||||
secondary_types: vec![],
|
||||
},
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type: Some(AlbumPrimaryType::Album),
|
||||
secondary_types: vec![],
|
||||
},
|
||||
tracks: vec![
|
||||
Track {
|
||||
@ -331,11 +315,11 @@ macro_rules! full_collection {
|
||||
id: ArtistId {
|
||||
name: "The Album_Artist ‘C’".to_string(),
|
||||
},
|
||||
sort: Some("Album_Artist ‘C’, The".to_string()),
|
||||
info: ArtistInfo {
|
||||
musicbrainz: MbRefOption::CannotHaveMbid,
|
||||
properties: HashMap::new(),
|
||||
},
|
||||
sort: Some(ArtistId {
|
||||
name: "Album_Artist ‘C’, The".to_string(),
|
||||
}),
|
||||
musicbrainz: MbRefOption::CannotHaveMbid,
|
||||
properties: HashMap::new(),
|
||||
},
|
||||
albums: vec![
|
||||
Album {
|
||||
@ -345,11 +329,9 @@ macro_rules! full_collection {
|
||||
},
|
||||
date: 1985.into(),
|
||||
seq: AlbumSeq(0),
|
||||
info: AlbumInfo {
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type: Some(AlbumPrimaryType::Album),
|
||||
secondary_types: vec![],
|
||||
},
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type: Some(AlbumPrimaryType::Album),
|
||||
secondary_types: vec![],
|
||||
},
|
||||
tracks: vec![
|
||||
Track {
|
||||
@ -386,11 +368,9 @@ macro_rules! full_collection {
|
||||
},
|
||||
date: 2018.into(),
|
||||
seq: AlbumSeq(0),
|
||||
info: AlbumInfo {
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type: Some(AlbumPrimaryType::Album),
|
||||
secondary_types: vec![],
|
||||
},
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type: Some(AlbumPrimaryType::Album),
|
||||
secondary_types: vec![],
|
||||
},
|
||||
tracks: vec![
|
||||
Track {
|
||||
@ -428,10 +408,8 @@ macro_rules! full_collection {
|
||||
name: "Album_Artist ‘D’".to_string(),
|
||||
},
|
||||
sort: None,
|
||||
info: ArtistInfo {
|
||||
musicbrainz: MbRefOption::None,
|
||||
properties: HashMap::new(),
|
||||
},
|
||||
musicbrainz: MbRefOption::None,
|
||||
properties: HashMap::new(),
|
||||
},
|
||||
albums: vec![
|
||||
Album {
|
||||
@ -441,11 +419,9 @@ macro_rules! full_collection {
|
||||
},
|
||||
date: 1995.into(),
|
||||
seq: AlbumSeq(0),
|
||||
info: AlbumInfo {
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type: Some(AlbumPrimaryType::Album),
|
||||
secondary_types: vec![],
|
||||
},
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type: Some(AlbumPrimaryType::Album),
|
||||
secondary_types: vec![],
|
||||
},
|
||||
tracks: vec![
|
||||
Track {
|
||||
@ -482,11 +458,9 @@ macro_rules! full_collection {
|
||||
},
|
||||
date: 2028.into(),
|
||||
seq: AlbumSeq(0),
|
||||
info: AlbumInfo {
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type: Some(AlbumPrimaryType::Album),
|
||||
secondary_types: vec![],
|
||||
},
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type: Some(AlbumPrimaryType::Album),
|
||||
secondary_types: vec![],
|
||||
},
|
||||
tracks: vec![
|
||||
Track {
|
||||
|
@ -8,10 +8,8 @@ macro_rules! library_collection {
|
||||
name: "Album_Artist ‘A’".to_string(),
|
||||
},
|
||||
sort: None,
|
||||
info: ArtistInfo {
|
||||
musicbrainz: MbRefOption::None,
|
||||
properties: HashMap::new(),
|
||||
},
|
||||
musicbrainz: MbRefOption::None,
|
||||
properties: HashMap::new(),
|
||||
},
|
||||
albums: vec![
|
||||
Album {
|
||||
@ -21,7 +19,9 @@ macro_rules! library_collection {
|
||||
},
|
||||
date: 1998.into(),
|
||||
seq: AlbumSeq(0),
|
||||
info: AlbumInfo::default(),
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type: None,
|
||||
secondary_types: vec![],
|
||||
},
|
||||
tracks: vec![
|
||||
Track {
|
||||
@ -80,7 +80,9 @@ macro_rules! library_collection {
|
||||
},
|
||||
date: (2015, 4).into(),
|
||||
seq: AlbumSeq(0),
|
||||
info: AlbumInfo::default(),
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type: None,
|
||||
secondary_types: vec![],
|
||||
},
|
||||
tracks: vec![
|
||||
Track {
|
||||
@ -115,10 +117,8 @@ macro_rules! library_collection {
|
||||
name: "Album_Artist ‘B’".to_string(),
|
||||
},
|
||||
sort: None,
|
||||
info: ArtistInfo {
|
||||
musicbrainz: MbRefOption::None,
|
||||
properties: HashMap::new(),
|
||||
},
|
||||
musicbrainz: MbRefOption::None,
|
||||
properties: HashMap::new(),
|
||||
},
|
||||
albums: vec![
|
||||
Album {
|
||||
@ -128,7 +128,9 @@ macro_rules! library_collection {
|
||||
},
|
||||
date: (2003, 6, 6).into(),
|
||||
seq: AlbumSeq(0),
|
||||
info: AlbumInfo::default(),
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type: None,
|
||||
secondary_types: vec![],
|
||||
},
|
||||
tracks: vec![
|
||||
Track {
|
||||
@ -165,7 +167,9 @@ macro_rules! library_collection {
|
||||
},
|
||||
date: 2008.into(),
|
||||
seq: AlbumSeq(0),
|
||||
info: AlbumInfo::default(),
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type: None,
|
||||
secondary_types: vec![],
|
||||
},
|
||||
tracks: vec![
|
||||
Track {
|
||||
@ -202,7 +206,9 @@ macro_rules! library_collection {
|
||||
},
|
||||
date: 2009.into(),
|
||||
seq: AlbumSeq(0),
|
||||
info: AlbumInfo::default(),
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type: None,
|
||||
secondary_types: vec![],
|
||||
},
|
||||
tracks: vec![
|
||||
Track {
|
||||
@ -239,7 +245,9 @@ macro_rules! library_collection {
|
||||
},
|
||||
date: 2015.into(),
|
||||
seq: AlbumSeq(0),
|
||||
info: AlbumInfo::default(),
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type: None,
|
||||
secondary_types: vec![],
|
||||
},
|
||||
tracks: vec![
|
||||
Track {
|
||||
@ -276,11 +284,11 @@ macro_rules! library_collection {
|
||||
id: ArtistId {
|
||||
name: "The Album_Artist ‘C’".to_string(),
|
||||
},
|
||||
sort: Some("Album_Artist ‘C’, The".to_string()),
|
||||
info: ArtistInfo {
|
||||
musicbrainz: MbRefOption::None,
|
||||
properties: HashMap::new(),
|
||||
},
|
||||
sort: Some(ArtistId {
|
||||
name: "Album_Artist ‘C’, The".to_string(),
|
||||
}),
|
||||
musicbrainz: MbRefOption::None,
|
||||
properties: HashMap::new(),
|
||||
},
|
||||
albums: vec![
|
||||
Album {
|
||||
@ -290,7 +298,9 @@ macro_rules! library_collection {
|
||||
},
|
||||
date: 1985.into(),
|
||||
seq: AlbumSeq(0),
|
||||
info: AlbumInfo::default(),
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type: None,
|
||||
secondary_types: vec![],
|
||||
},
|
||||
tracks: vec![
|
||||
Track {
|
||||
@ -327,7 +337,9 @@ macro_rules! library_collection {
|
||||
},
|
||||
date: 2018.into(),
|
||||
seq: AlbumSeq(0),
|
||||
info: AlbumInfo::default(),
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type: None,
|
||||
secondary_types: vec![],
|
||||
},
|
||||
tracks: vec![
|
||||
Track {
|
||||
@ -365,10 +377,8 @@ macro_rules! library_collection {
|
||||
name: "Album_Artist ‘D’".to_string(),
|
||||
},
|
||||
sort: None,
|
||||
info: ArtistInfo {
|
||||
musicbrainz: MbRefOption::None,
|
||||
properties: HashMap::new(),
|
||||
},
|
||||
musicbrainz: MbRefOption::None,
|
||||
properties: HashMap::new(),
|
||||
},
|
||||
albums: vec![
|
||||
Album {
|
||||
@ -378,7 +388,9 @@ macro_rules! library_collection {
|
||||
},
|
||||
date: 1995.into(),
|
||||
seq: AlbumSeq(0),
|
||||
info: AlbumInfo::default(),
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type: None,
|
||||
secondary_types: vec![],
|
||||
},
|
||||
tracks: vec![
|
||||
Track {
|
||||
@ -415,7 +427,9 @@ macro_rules! library_collection {
|
||||
},
|
||||
date: 2028.into(),
|
||||
seq: AlbumSeq(0),
|
||||
info: AlbumInfo::default(),
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type: None,
|
||||
secondary_types: vec![],
|
||||
},
|
||||
tracks: vec![
|
||||
Track {
|
||||
|
@ -156,12 +156,12 @@ impl AppMachine<FetchState> {
|
||||
result_sender: ResultSender,
|
||||
artist: &Artist,
|
||||
) -> Result<(), FetchError> {
|
||||
let requests = match artist.meta.info.musicbrainz {
|
||||
let requests = match artist.meta.musicbrainz {
|
||||
MbRefOption::Some(ref arid) => {
|
||||
let arid = arid.mbid();
|
||||
let albums = artist.albums.iter();
|
||||
albums
|
||||
.filter(|album| matches!(album.meta.info.musicbrainz, MbRefOption::None))
|
||||
.filter(|album| matches!(album.meta.musicbrainz, MbRefOption::None))
|
||||
.map(|album| {
|
||||
MbParams::search_release_group(
|
||||
artist.meta.id.clone(),
|
||||
|
@ -26,13 +26,12 @@ macro_rules! item_option_artist_set {
|
||||
music_hoard: &mut dyn IMusicHoard,
|
||||
meta: &ArtistMeta,
|
||||
) -> Result<(), musichoard::Error> {
|
||||
let mut info = meta.info.clone();
|
||||
info.musicbrainz = match self {
|
||||
MatchOption::Some(m) => m.item.info.musicbrainz,
|
||||
let mbref = match self {
|
||||
MatchOption::Some(m) => m.item.musicbrainz,
|
||||
MatchOption::CannotHaveMbid => MbRefOption::CannotHaveMbid,
|
||||
MatchOption::ManualInputMbid => panic!(),
|
||||
};
|
||||
music_hoard.set_artist_info(&meta.id, info)
|
||||
music_hoard.set_artist_musicbrainz(&meta.id, mbref)
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -50,17 +49,19 @@ macro_rules! item_option_album_set {
|
||||
artist: &ArtistId,
|
||||
meta: &AlbumMeta,
|
||||
) -> Result<(), musichoard::Error> {
|
||||
let mut info = meta.info.clone();
|
||||
(info.musicbrainz, info.primary_type, info.secondary_types) = match self {
|
||||
let (mbref, primary_type, secondary_types) = match self {
|
||||
MatchOption::Some(m) => (
|
||||
m.item.info.musicbrainz,
|
||||
m.item.info.primary_type,
|
||||
m.item.info.secondary_types,
|
||||
m.item.musicbrainz,
|
||||
m.item.primary_type,
|
||||
m.item.secondary_types,
|
||||
),
|
||||
MatchOption::CannotHaveMbid => (MbRefOption::CannotHaveMbid, None, Vec::new()),
|
||||
MatchOption::ManualInputMbid => panic!(),
|
||||
};
|
||||
music_hoard.set_album_info(artist, &meta.id, info)
|
||||
music_hoard.set_album_musicbrainz(artist, &meta.id, mbref)?;
|
||||
music_hoard.set_album_primary_type(artist, &meta.id, primary_type)?;
|
||||
music_hoard.set_album_secondary_types(artist, &meta.id, secondary_types)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -342,7 +343,7 @@ mod tests {
|
||||
|
||||
use mockall::predicate;
|
||||
use musichoard::collection::{
|
||||
album::{AlbumDate, AlbumId, AlbumInfo, AlbumMeta, AlbumPrimaryType, AlbumSecondaryType},
|
||||
album::{AlbumDate, AlbumId, AlbumMeta, AlbumPrimaryType, AlbumSecondaryType},
|
||||
artist::{ArtistId, ArtistMeta},
|
||||
};
|
||||
|
||||
@ -403,11 +404,8 @@ mod tests {
|
||||
let album = AlbumMeta::new(
|
||||
AlbumId::new("Album"),
|
||||
AlbumDate::new(Some(1990), Some(5), None),
|
||||
AlbumInfo::new(
|
||||
MbRefOption::None,
|
||||
Some(AlbumPrimaryType::Album),
|
||||
vec![AlbumSecondaryType::Live, AlbumSecondaryType::Compilation],
|
||||
),
|
||||
Some(AlbumPrimaryType::Album),
|
||||
vec![AlbumSecondaryType::Live, AlbumSecondaryType::Compilation],
|
||||
);
|
||||
|
||||
let album_1 = album.clone();
|
||||
@ -415,7 +413,7 @@ mod tests {
|
||||
|
||||
let mut album_2 = album.clone();
|
||||
album_2.id.title.push_str(" extra title part");
|
||||
album_2.info.secondary_types.pop();
|
||||
album_2.secondary_types.pop();
|
||||
let album_match_2 = Match::new(100, album_2);
|
||||
|
||||
let list = vec![album_match_1.clone(), album_match_2.clone()];
|
||||
@ -427,11 +425,8 @@ mod tests {
|
||||
let album = AlbumMeta::new(
|
||||
AlbumId::new("Album"),
|
||||
AlbumDate::new(Some(1990), Some(5), None),
|
||||
AlbumInfo::new(
|
||||
MbRefOption::None,
|
||||
Some(AlbumPrimaryType::Album),
|
||||
vec![AlbumSecondaryType::Live, AlbumSecondaryType::Compilation],
|
||||
),
|
||||
Some(AlbumPrimaryType::Album),
|
||||
vec![AlbumSecondaryType::Live, AlbumSecondaryType::Compilation],
|
||||
);
|
||||
let lookup = Lookup::new(album.clone());
|
||||
MatchStateInfo::album_lookup(artist_id, album, lookup)
|
||||
@ -647,7 +642,7 @@ mod tests {
|
||||
fn select_manual_input_album() {
|
||||
let mut mb_job_sender = MockIMbJobSender::new();
|
||||
let artist_id = ArtistId::new("Artist");
|
||||
let album = AlbumMeta::new("Album", 1990, AlbumInfo::default());
|
||||
let album = AlbumMeta::new("Album", 1990, None, vec![]);
|
||||
let requests = VecDeque::from([MbParams::lookup_release_group(
|
||||
artist_id.clone(),
|
||||
album.clone(),
|
||||
|
@ -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.name, !case_sens, !char_sens);
|
||||
result = name.starts_with(search);
|
||||
}
|
||||
}
|
||||
|
@ -205,14 +205,14 @@ impl KeySelectArtist {
|
||||
let artist = &artists[index];
|
||||
let key = artist.meta.get_sort_key();
|
||||
KeySelectArtist {
|
||||
key: (key.0.into(),),
|
||||
key: (key.0.to_owned(),),
|
||||
album: KeySelectAlbum::get(&artist.albums, &selection.album),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_sort_key(&self) -> (&str,) {
|
||||
(&self.key.0.name,)
|
||||
pub fn get_sort_key(&self) -> (&ArtistId,) {
|
||||
(&self.key.0,)
|
||||
}
|
||||
}
|
||||
|
||||
|
48
src/tui/lib/external/musicbrainz/api/mod.rs
vendored
48
src/tui/lib/external/musicbrainz/api/mod.rs
vendored
@ -4,8 +4,8 @@ use std::collections::HashMap;
|
||||
|
||||
use musichoard::{
|
||||
collection::{
|
||||
album::{AlbumDate, AlbumInfo, AlbumMeta, AlbumSeq},
|
||||
artist::{ArtistInfo, ArtistMeta},
|
||||
album::{AlbumDate, AlbumMeta, AlbumSeq},
|
||||
artist::{ArtistId, ArtistMeta},
|
||||
musicbrainz::{MbRefOption, Mbid},
|
||||
},
|
||||
external::musicbrainz::{
|
||||
@ -93,15 +93,15 @@ impl<Http: IMusicBrainzHttp> IMusicBrainz for MusicBrainz<Http> {
|
||||
}
|
||||
|
||||
fn from_lookup_artist_response(entity: LookupArtistResponse) -> Lookup<ArtistMeta> {
|
||||
let sort = Some(entity.meta.sort_name).filter(|s| s != &entity.meta.name);
|
||||
let sort: Option<ArtistId> = Some(entity.meta.sort_name)
|
||||
.filter(|s| s != &entity.meta.name)
|
||||
.map(Into::into);
|
||||
Lookup {
|
||||
item: ArtistMeta {
|
||||
id: entity.meta.name.into(),
|
||||
id: entity.meta.name,
|
||||
sort,
|
||||
info: ArtistInfo {
|
||||
musicbrainz: MbRefOption::Some(entity.meta.id.into()),
|
||||
properties: HashMap::new(),
|
||||
},
|
||||
musicbrainz: MbRefOption::Some(entity.meta.id.into()),
|
||||
properties: HashMap::new(),
|
||||
},
|
||||
disambiguation: entity.meta.disambiguation,
|
||||
}
|
||||
@ -110,30 +110,28 @@ fn from_lookup_artist_response(entity: LookupArtistResponse) -> Lookup<ArtistMet
|
||||
fn from_lookup_release_group_response(entity: LookupReleaseGroupResponse) -> Lookup<AlbumMeta> {
|
||||
Lookup {
|
||||
item: AlbumMeta {
|
||||
id: entity.meta.title.into(),
|
||||
id: entity.meta.title,
|
||||
date: entity.meta.first_release_date,
|
||||
seq: AlbumSeq::default(),
|
||||
info: AlbumInfo {
|
||||
musicbrainz: MbRefOption::Some(entity.meta.id.into()),
|
||||
primary_type: Some(entity.meta.primary_type),
|
||||
secondary_types: entity.meta.secondary_types.unwrap_or_default(),
|
||||
},
|
||||
musicbrainz: MbRefOption::Some(entity.meta.id.into()),
|
||||
primary_type: Some(entity.meta.primary_type),
|
||||
secondary_types: entity.meta.secondary_types.unwrap_or_default(),
|
||||
},
|
||||
disambiguation: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn from_search_artist_response_artist(entity: SearchArtistResponseArtist) -> Match<ArtistMeta> {
|
||||
let sort = Some(entity.meta.sort_name).filter(|s| s != &entity.meta.name);
|
||||
let sort: Option<ArtistId> = Some(entity.meta.sort_name)
|
||||
.filter(|s| s != &entity.meta.name)
|
||||
.map(Into::into);
|
||||
Match {
|
||||
score: entity.score,
|
||||
item: ArtistMeta {
|
||||
id: entity.meta.name.into(),
|
||||
id: entity.meta.name,
|
||||
sort,
|
||||
info: ArtistInfo {
|
||||
musicbrainz: MbRefOption::Some(entity.meta.id.into()),
|
||||
properties: HashMap::new(),
|
||||
},
|
||||
musicbrainz: MbRefOption::Some(entity.meta.id.into()),
|
||||
properties: HashMap::new(),
|
||||
},
|
||||
disambiguation: entity.meta.disambiguation,
|
||||
}
|
||||
@ -145,14 +143,12 @@ fn from_search_release_group_response_release_group(
|
||||
Match {
|
||||
score: entity.score,
|
||||
item: AlbumMeta {
|
||||
id: entity.meta.title.into(),
|
||||
id: entity.meta.title,
|
||||
date: entity.meta.first_release_date,
|
||||
seq: AlbumSeq::default(),
|
||||
info: AlbumInfo {
|
||||
musicbrainz: MbRefOption::Some(entity.meta.id.into()),
|
||||
primary_type: Some(entity.meta.primary_type),
|
||||
secondary_types: entity.meta.secondary_types.unwrap_or_default(),
|
||||
},
|
||||
musicbrainz: MbRefOption::Some(entity.meta.id.into()),
|
||||
primary_type: Some(entity.meta.primary_type),
|
||||
secondary_types: entity.meta.secondary_types.unwrap_or_default(),
|
||||
},
|
||||
disambiguation: None,
|
||||
}
|
||||
|
@ -419,7 +419,7 @@ mod tests {
|
||||
}
|
||||
|
||||
fn search_albums_requests() -> VecDeque<MbParams> {
|
||||
let mbref = mb_ref_opt_as_ref(&COLLECTION[1].meta.info.musicbrainz);
|
||||
let mbref = mb_ref_opt_as_ref(&COLLECTION[1].meta.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.info.musicbrainz);
|
||||
let mbref = mb_ref_opt_as_ref(&COLLECTION[1].meta.musicbrainz);
|
||||
mb_ref_opt_unwrap(mbref).mbid().clone()
|
||||
}
|
||||
|
||||
|
@ -3,8 +3,9 @@ pub mod interface;
|
||||
|
||||
use musichoard::{
|
||||
collection::{
|
||||
album::{AlbumId, AlbumInfo},
|
||||
artist::{ArtistId, ArtistInfo},
|
||||
album::{AlbumId, AlbumPrimaryType, AlbumSecondaryType},
|
||||
artist::ArtistId,
|
||||
musicbrainz::{MbAlbumRef, MbArtistRef, MbRefOption},
|
||||
Collection,
|
||||
},
|
||||
interface::{database::IDatabase, library::ILibrary},
|
||||
@ -20,13 +21,28 @@ pub trait IMusicHoard {
|
||||
fn reload_database(&mut self) -> Result<(), musichoard::Error>;
|
||||
fn get_collection(&self) -> &Collection;
|
||||
|
||||
fn set_artist_info(&mut self, id: &ArtistId, info: ArtistInfo)
|
||||
-> Result<(), musichoard::Error>;
|
||||
fn set_album_info(
|
||||
fn set_artist_musicbrainz(
|
||||
&mut self,
|
||||
id: &ArtistId,
|
||||
mbref: MbRefOption<MbArtistRef>,
|
||||
) -> Result<(), musichoard::Error>;
|
||||
fn set_album_musicbrainz(
|
||||
&mut self,
|
||||
artist_id: &ArtistId,
|
||||
album_id: &AlbumId,
|
||||
info: AlbumInfo,
|
||||
mbref: MbRefOption<MbAlbumRef>,
|
||||
) -> Result<(), musichoard::Error>;
|
||||
fn set_album_primary_type(
|
||||
&mut self,
|
||||
artist_id: &ArtistId,
|
||||
album_id: &AlbumId,
|
||||
primary_type: Option<AlbumPrimaryType>,
|
||||
) -> Result<(), musichoard::Error>;
|
||||
fn set_album_secondary_types(
|
||||
&mut self,
|
||||
artist_id: &ArtistId,
|
||||
album_id: &AlbumId,
|
||||
secondary_types: Vec<AlbumSecondaryType>,
|
||||
) -> Result<(), musichoard::Error>;
|
||||
}
|
||||
|
||||
@ -44,21 +60,49 @@ impl<Database: IDatabase, Library: ILibrary> IMusicHoard for MusicHoard<Database
|
||||
<Self as IMusicHoardBase>::get_collection(self)
|
||||
}
|
||||
|
||||
fn set_artist_info(
|
||||
fn set_artist_musicbrainz(
|
||||
&mut self,
|
||||
id: &ArtistId,
|
||||
info: ArtistInfo,
|
||||
mbref: MbRefOption<MbArtistRef>,
|
||||
) -> Result<(), musichoard::Error> {
|
||||
<Self as IMusicHoardDatabase>::set_artist_info(self, id, info)
|
||||
<Self as IMusicHoardDatabase>::set_artist_musicbrainz(self, id, mbref)
|
||||
}
|
||||
|
||||
fn set_album_info(
|
||||
fn set_album_musicbrainz(
|
||||
&mut self,
|
||||
artist_id: &ArtistId,
|
||||
album_id: &AlbumId,
|
||||
info: AlbumInfo,
|
||||
mbref: MbRefOption<MbAlbumRef>,
|
||||
) -> Result<(), musichoard::Error> {
|
||||
<Self as IMusicHoardDatabase>::set_album_info(self, artist_id, album_id, info)
|
||||
<Self as IMusicHoardDatabase>::set_album_musicbrainz(self, artist_id, album_id, mbref)
|
||||
}
|
||||
|
||||
fn set_album_primary_type(
|
||||
&mut self,
|
||||
artist_id: &ArtistId,
|
||||
album_id: &AlbumId,
|
||||
primary_type: Option<AlbumPrimaryType>,
|
||||
) -> Result<(), musichoard::Error> {
|
||||
<Self as IMusicHoardDatabase>::set_album_primary_type(
|
||||
self,
|
||||
artist_id,
|
||||
album_id,
|
||||
primary_type,
|
||||
)
|
||||
}
|
||||
|
||||
fn set_album_secondary_types(
|
||||
&mut self,
|
||||
artist_id: &ArtistId,
|
||||
album_id: &AlbumId,
|
||||
secondary_types: Vec<AlbumSecondaryType>,
|
||||
) -> Result<(), musichoard::Error> {
|
||||
<Self as IMusicHoardDatabase>::set_album_secondary_types(
|
||||
self,
|
||||
artist_id,
|
||||
album_id,
|
||||
secondary_types,
|
||||
)
|
||||
}
|
||||
}
|
||||
// GRCOV_EXCL_STOP
|
||||
|
@ -1,8 +1,8 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use musichoard::collection::{
|
||||
album::{Album, AlbumId, AlbumInfo, AlbumMeta, AlbumPrimaryType, AlbumSeq},
|
||||
artist::{Artist, ArtistId, ArtistInfo, ArtistMeta},
|
||||
album::{Album, AlbumId, AlbumMeta, AlbumPrimaryType, AlbumSeq},
|
||||
artist::{Artist, ArtistId, ArtistMeta},
|
||||
musicbrainz::{MbAlbumRef, MbArtistRef, MbRefOption},
|
||||
track::{Track, TrackFormat, TrackId, TrackNum, TrackQuality},
|
||||
};
|
||||
|
@ -169,10 +169,7 @@ impl<'a, 'b> AlbumState<'a, 'b> {
|
||||
.map(|a| UiDisplay::display_date(&a.meta.date, &a.meta.seq))
|
||||
.unwrap_or_default(),
|
||||
album
|
||||
.map(|a| UiDisplay::display_type(
|
||||
&a.meta.info.primary_type,
|
||||
&a.meta.info.secondary_types
|
||||
))
|
||||
.map(|a| UiDisplay::display_type(&a.meta.primary_type, &a.meta.secondary_types))
|
||||
.unwrap_or_default(),
|
||||
album
|
||||
.map(|a| UiDisplay::display_album_status(&a.get_status()))
|
||||
|
@ -195,7 +195,7 @@ impl UiDisplay {
|
||||
"{:010} | {} [{}]",
|
||||
UiDisplay::display_album_date(&album.date),
|
||||
album.id.title,
|
||||
UiDisplay::display_type(&album.info.primary_type, &album.info.secondary_types),
|
||||
UiDisplay::display_type(&album.primary_type, &album.secondary_types),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -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.info.musicbrainz))
|
||||
.map(|a| UiDisplay::display_mb_ref_option_as_url(&a.meta.musicbrainz))
|
||||
.unwrap_or_default(),
|
||||
Self::opt_hashmap_to_string(
|
||||
artist.map(|a| &a.meta.info.properties),
|
||||
artist.map(|a| &a.meta.properties),
|
||||
&double_item_indent,
|
||||
&double_list_indent
|
||||
),
|
||||
@ -104,7 +104,7 @@ impl<'a> AlbumOverlay<'a> {
|
||||
MusicBrainz: {}",
|
||||
album.map(|a| a.meta.id.title.as_str()).unwrap_or(""),
|
||||
album
|
||||
.map(|a| UiDisplay::display_mb_ref_option_as_url(&a.meta.info.musicbrainz))
|
||||
.map(|a| UiDisplay::display_mb_ref_option_as_url(&a.meta.musicbrainz))
|
||||
.unwrap_or_default(),
|
||||
));
|
||||
|
||||
|
@ -201,9 +201,8 @@ impl IUi for Ui {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use musichoard::collection::{
|
||||
album::{AlbumDate, AlbumId, AlbumInfo, AlbumMeta, AlbumPrimaryType, AlbumSecondaryType},
|
||||
album::{AlbumDate, AlbumId, AlbumMeta, AlbumPrimaryType, AlbumSecondaryType},
|
||||
artist::{Artist, ArtistId, ArtistMeta},
|
||||
musicbrainz::MbRefOption,
|
||||
};
|
||||
|
||||
use crate::tui::{
|
||||
@ -382,11 +381,8 @@ mod tests {
|
||||
AlbumMeta::new(
|
||||
AlbumId::new("An Album"),
|
||||
AlbumDate::new(Some(1990), Some(5), None),
|
||||
AlbumInfo::new(
|
||||
MbRefOption::None,
|
||||
Some(AlbumPrimaryType::Album),
|
||||
vec![AlbumSecondaryType::Live, AlbumSecondaryType::Compilation],
|
||||
),
|
||||
Some(AlbumPrimaryType::Album),
|
||||
vec![AlbumSecondaryType::Live, AlbumSecondaryType::Compilation],
|
||||
)
|
||||
}
|
||||
|
||||
|
188
tests/testlib.rs
188
tests/testlib.rs
@ -2,8 +2,8 @@ use once_cell::sync::Lazy;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use musichoard::collection::{
|
||||
album::{Album, AlbumId, AlbumInfo, AlbumMeta, AlbumPrimaryType, AlbumSecondaryType, AlbumSeq},
|
||||
artist::{Artist, ArtistId, ArtistInfo, ArtistMeta},
|
||||
album::{Album, AlbumId, AlbumMeta, AlbumPrimaryType, AlbumSecondaryType, AlbumSeq},
|
||||
artist::{Artist, ArtistId, ArtistMeta},
|
||||
musicbrainz::{MbArtistRef, MbRefOption},
|
||||
track::{Track, TrackFormat, TrackId, TrackNum, TrackQuality},
|
||||
Collection,
|
||||
@ -16,23 +16,23 @@ pub static COLLECTION: Lazy<Vec<Artist>> = Lazy::new(|| -> Collection {
|
||||
id: ArtistId {
|
||||
name: String::from("Аркона"),
|
||||
},
|
||||
sort: Some(String::from("Arkona")),
|
||||
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",
|
||||
)]),
|
||||
sort: Some(ArtistId{
|
||||
name: 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"),
|
||||
]),
|
||||
},
|
||||
(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 {
|
||||
@ -41,11 +41,9 @@ pub static COLLECTION: Lazy<Vec<Artist>> = Lazy::new(|| -> Collection {
|
||||
},
|
||||
date: 2011.into(),
|
||||
seq: AlbumSeq(0),
|
||||
info: AlbumInfo {
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type: Some(AlbumPrimaryType::Album),
|
||||
secondary_types: vec![],
|
||||
},
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type: Some(AlbumPrimaryType::Album),
|
||||
secondary_types: vec![],
|
||||
},
|
||||
tracks: vec![
|
||||
Track {
|
||||
@ -211,19 +209,17 @@ pub static COLLECTION: Lazy<Vec<Artist>> = Lazy::new(|| -> Collection {
|
||||
name: String::from("Eluveitie"),
|
||||
},
|
||||
sort: None,
|
||||
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",
|
||||
)]),
|
||||
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",
|
||||
)]),
|
||||
]),
|
||||
},
|
||||
albums: vec![
|
||||
Album {
|
||||
@ -233,11 +229,9 @@ pub static COLLECTION: Lazy<Vec<Artist>> = Lazy::new(|| -> Collection {
|
||||
},
|
||||
date: 2004.into(),
|
||||
seq: AlbumSeq(0),
|
||||
info: AlbumInfo {
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type: Some(AlbumPrimaryType::Ep),
|
||||
secondary_types: vec![],
|
||||
},
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type: Some(AlbumPrimaryType::Ep),
|
||||
secondary_types: vec![],
|
||||
},
|
||||
tracks: vec![
|
||||
Track {
|
||||
@ -315,11 +309,9 @@ pub static COLLECTION: Lazy<Vec<Artist>> = Lazy::new(|| -> Collection {
|
||||
},
|
||||
date: 2008.into(),
|
||||
seq: AlbumSeq(0),
|
||||
info: AlbumInfo {
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type: Some(AlbumPrimaryType::Album),
|
||||
secondary_types: vec![],
|
||||
},
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type: Some(AlbumPrimaryType::Album),
|
||||
secondary_types: vec![],
|
||||
},
|
||||
tracks: vec![
|
||||
Track {
|
||||
@ -464,19 +456,17 @@ pub static COLLECTION: Lazy<Vec<Artist>> = Lazy::new(|| -> Collection {
|
||||
name: String::from("Frontside"),
|
||||
},
|
||||
sort: None,
|
||||
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",
|
||||
)]),
|
||||
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",
|
||||
)]),
|
||||
]),
|
||||
},
|
||||
albums: vec![Album {
|
||||
meta: AlbumMeta {
|
||||
@ -485,11 +475,9 @@ pub static COLLECTION: Lazy<Vec<Artist>> = Lazy::new(|| -> Collection {
|
||||
},
|
||||
date: 2001.into(),
|
||||
seq: AlbumSeq(0),
|
||||
info: AlbumInfo {
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type: Some(AlbumPrimaryType::Album),
|
||||
secondary_types: vec![],
|
||||
},
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type: Some(AlbumPrimaryType::Album),
|
||||
secondary_types: vec![],
|
||||
},
|
||||
tracks: vec![
|
||||
Track {
|
||||
@ -621,20 +609,20 @@ pub static COLLECTION: Lazy<Vec<Artist>> = Lazy::new(|| -> Collection {
|
||||
id: ArtistId {
|
||||
name: String::from("Heaven’s Basement"),
|
||||
},
|
||||
sort: Some(String::from("Heaven’s Basement")),
|
||||
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",
|
||||
)]),
|
||||
sort: Some(ArtistId {
|
||||
name: 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"),
|
||||
]),
|
||||
},
|
||||
(String::from("Qobuz"), vec![String::from(
|
||||
"https://www.qobuz.com/nl-nl/interpreter/heaven-s-basement/download-streaming-albums",
|
||||
)]),
|
||||
]),
|
||||
},
|
||||
albums: vec![Album {
|
||||
meta: AlbumMeta {
|
||||
@ -643,7 +631,9 @@ pub static COLLECTION: Lazy<Vec<Artist>> = Lazy::new(|| -> Collection {
|
||||
},
|
||||
date: 2011.into(),
|
||||
seq: AlbumSeq(0),
|
||||
info: AlbumInfo::default(),
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type: None,
|
||||
secondary_types: vec![],
|
||||
},
|
||||
tracks: vec![
|
||||
Track {
|
||||
@ -665,11 +655,9 @@ pub static COLLECTION: Lazy<Vec<Artist>> = Lazy::new(|| -> Collection {
|
||||
},
|
||||
date: 2011.into(),
|
||||
seq: AlbumSeq(0),
|
||||
info: AlbumInfo {
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type: Some(AlbumPrimaryType::Album),
|
||||
secondary_types: vec![],
|
||||
},
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type: Some(AlbumPrimaryType::Album),
|
||||
secondary_types: vec![],
|
||||
},
|
||||
tracks: vec![
|
||||
Track {
|
||||
@ -758,19 +746,17 @@ pub static COLLECTION: Lazy<Vec<Artist>> = Lazy::new(|| -> Collection {
|
||||
name: String::from("Metallica"),
|
||||
},
|
||||
sort: None,
|
||||
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",
|
||||
)]),
|
||||
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",
|
||||
)]),
|
||||
]),
|
||||
},
|
||||
albums: vec![
|
||||
Album {
|
||||
@ -780,11 +766,9 @@ pub static COLLECTION: Lazy<Vec<Artist>> = Lazy::new(|| -> Collection {
|
||||
},
|
||||
date: 1984.into(),
|
||||
seq: AlbumSeq(0),
|
||||
info: AlbumInfo {
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type: Some(AlbumPrimaryType::Album),
|
||||
secondary_types: vec![],
|
||||
},
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type: Some(AlbumPrimaryType::Album),
|
||||
secondary_types: vec![],
|
||||
},
|
||||
tracks: vec![
|
||||
Track {
|
||||
@ -884,11 +868,9 @@ pub static COLLECTION: Lazy<Vec<Artist>> = Lazy::new(|| -> Collection {
|
||||
},
|
||||
date: 1999.into(),
|
||||
seq: AlbumSeq(0),
|
||||
info: AlbumInfo {
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type: Some(AlbumPrimaryType::Album),
|
||||
secondary_types: vec![AlbumSecondaryType::Live],
|
||||
},
|
||||
musicbrainz: MbRefOption::None,
|
||||
primary_type: Some(AlbumPrimaryType::Album),
|
||||
secondary_types: vec![AlbumSecondaryType::Live],
|
||||
},
|
||||
tracks: vec![
|
||||
Track {
|
||||
|
Loading…
Reference in New Issue
Block a user