Merge and write library id
Some checks failed
Cargo CI / Build and Test (pull_request) Failing after 1m18s
Cargo CI / Lint (pull_request) Failing after 1m7s

This commit is contained in:
Wojciech Kozlowski 2025-01-02 09:19:33 +01:00
parent c03bfe5021
commit 5f992b4b2c
15 changed files with 159 additions and 46 deletions

View File

@ -4,7 +4,7 @@ use std::{
}; };
use crate::core::collection::{ use crate::core::collection::{
merge::{Merge, MergeSorted, WithId}, merge::{Merge, MergeSorted},
musicbrainz::{MbAlbumRef, MbRefOption}, musicbrainz::{MbAlbumRef, MbRefOption},
track::{Track, TrackFormat}, track::{Track, TrackFormat},
}; };
@ -33,28 +33,27 @@ pub struct AlbumInfo {
pub secondary_types: Vec<AlbumSecondaryType>, pub secondary_types: Vec<AlbumSecondaryType>,
} }
impl WithId for Album {
type Id = AlbumId;
fn id(&self) -> &Self::Id {
&self.meta.id
}
}
/// The album identifier. /// The album identifier.
#[derive(Clone, Debug, PartialEq, PartialOrd, Ord, Eq, Hash)] #[derive(Clone, Debug, PartialEq, PartialOrd, Ord, Eq, Hash)]
pub struct AlbumId { pub struct AlbumId {
pub title: String, pub title: String,
pub lib_id: AlbumLibId,
} }
/// Unique library identifier. /// Unique library identifier.
#[derive(Clone, Debug, PartialEq, PartialOrd, Ord, Eq, Hash)] #[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Ord, Eq, Hash)]
pub enum AlbumLibId { pub enum AlbumLibId {
Some(u32), Some(u32),
Singleton, Singleton,
None, None,
} }
impl AlbumLibId {
pub fn is_none(&self) -> bool {
matches!(self, AlbumLibId::None)
}
}
// There are crates for handling dates, but we don't need much complexity beyond year-month-day. // There are crates for handling dates, but we don't need much complexity beyond year-month-day.
/// The album's release date. /// The album's release date.
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord)] #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
@ -260,7 +259,12 @@ impl Ord for AlbumMeta {
impl Merge for AlbumMeta { impl Merge for AlbumMeta {
fn merge_in_place(&mut self, other: Self) { fn merge_in_place(&mut self, other: Self) {
assert_eq!(self.id, other.id); if !self.id.lib_id.is_none() && !other.id.lib_id.is_none() {
assert_eq!(self.id, other.id);
} else {
assert_eq!(self.id.title, other.id.title);
}
self.seq = std::cmp::max(self.seq, other.seq); self.seq = std::cmp::max(self.seq, other.seq);
self.info.merge_in_place(other.info); self.info.merge_in_place(other.info);
@ -291,7 +295,7 @@ impl AsRef<AlbumId> for AlbumId {
impl AlbumId { impl AlbumId {
pub fn new<S: Into<String>>(name: S) -> AlbumId { pub fn new<S: Into<String>>(name: S) -> AlbumId {
AlbumId { title: name.into() } AlbumId { title: name.into(), lib_id: AlbumLibId::None }
} }
} }
@ -323,15 +327,11 @@ mod tests {
fn same_date_seq_cmp() { fn same_date_seq_cmp() {
let date: AlbumDate = (2024, 3, 2).into(); let date: AlbumDate = (2024, 3, 2).into();
let album_id_1 = AlbumId { let album_id_1 = AlbumId::new("album z");
title: String::from("album z"),
};
let mut album_1 = Album::new(album_id_1).with_date(date.clone()); let mut album_1 = Album::new(album_id_1).with_date(date.clone());
album_1.meta.set_seq(AlbumSeq(1)); album_1.meta.set_seq(AlbumSeq(1));
let album_id_2 = AlbumId { let album_id_2 = AlbumId::new("album a");
title: String::from("album a"),
};
let mut album_2 = Album::new(album_id_2).with_date(date.clone()); let mut album_2 = Album::new(album_id_2).with_date(date.clone());
album_2.meta.set_seq(AlbumSeq(2)); album_2.meta.set_seq(AlbumSeq(2));

View File

@ -6,10 +6,12 @@ use std::{
use crate::core::collection::{ use crate::core::collection::{
album::Album, album::Album,
merge::{Merge, MergeCollections, WithId}, merge::{Merge, MergeId},
musicbrainz::{MbArtistRef, MbRefOption}, musicbrainz::{MbArtistRef, MbRefOption},
}; };
use super::album::AlbumLibId;
/// An artist. /// An artist.
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
pub struct Artist { pub struct Artist {
@ -32,7 +34,7 @@ pub struct ArtistInfo {
pub properties: HashMap<String, Vec<String>>, pub properties: HashMap<String, Vec<String>>,
} }
impl WithId for Artist { impl MergeId for Artist {
type Id = ArtistId; type Id = ArtistId;
fn id(&self) -> &Self::Id { fn id(&self) -> &Self::Id {
@ -71,8 +73,50 @@ impl Ord for Artist {
impl Merge for Artist { impl Merge for Artist {
fn merge_in_place(&mut self, other: Self) { fn merge_in_place(&mut self, other: Self) {
self.meta.merge_in_place(other.meta); self.meta.merge_in_place(other.meta);
let albums = mem::take(&mut self.albums);
self.albums = MergeCollections::merge_iter(albums, other.albums); let mut primary_albums = mem::take(&mut self.albums);
let mut secondary_albums = other.albums;
let mut secondary_without_id = HashMap::<String, Vec<Album>>::new();
for mut secondary_album in secondary_albums.drain(..) {
match secondary_album.meta.id.lib_id {
lib_id @ AlbumLibId::Some(_) | lib_id @ AlbumLibId::Singleton => {
match primary_albums
.iter_mut()
.find(|album| album.meta.id.lib_id == lib_id)
{
Some(ref mut primary_album) => {
primary_album.merge_in_place(secondary_album)
}
None => {
secondary_album.meta.id.lib_id = AlbumLibId::None;
primary_albums.push(secondary_album);
}
}
}
AlbumLibId::None => secondary_without_id
.entry(secondary_album.meta.id.title.clone())
.or_default()
.push(secondary_album),
}
}
for (title, mut secondary_albums) in secondary_without_id.drain() {
match primary_albums
.iter_mut()
.find(|album| album.meta.id.title == title)
{
Some(ref mut primary_album) => {
// We do not support merging multiple DB albums with same title yet.
assert_eq!(secondary_albums.len(), 1);
primary_album.merge_in_place(secondary_albums.pop().unwrap())
}
None => primary_albums.append(&mut secondary_albums),
}
}
primary_albums.sort_unstable();
self.albums = primary_albums;
} }
} }

View File

@ -80,7 +80,7 @@ where
} }
} }
pub trait WithId { pub trait MergeId {
type Id; type Id;
fn id(&self) -> &Self::Id; fn id(&self) -> &Self::Id;
@ -95,7 +95,7 @@ pub struct MergeCollections<ID, T, IT> {
impl<ID, T, IT> MergeCollections<ID, T, IT> impl<ID, T, IT> MergeCollections<ID, T, IT>
where where
ID: Eq + Hash + Clone, ID: Eq + Hash + Clone,
T: WithId<Id = ID> + Merge + Ord, T: MergeId<Id = ID> + Merge + Ord,
IT: IntoIterator<Item = T>, IT: IntoIterator<Item = T>,
{ {
pub fn merge_iter(primary: IT, secondary: IT) -> Vec<T> { pub fn merge_iter(primary: IT, secondary: IT) -> Vec<T> {

View File

@ -56,6 +56,7 @@ impl<Database, Library: ILibrary> MusicHoard<Database, Library> {
let album_id = AlbumId { let album_id = AlbumId {
title: item.album_title, title: item.album_title,
lib_id: item.album_lib_id,
}; };
let album_date = AlbumDate { let album_date = AlbumDate {

View File

@ -2,7 +2,7 @@ use once_cell::sync::Lazy;
use std::collections::HashMap; use std::collections::HashMap;
use crate::core::collection::{ use crate::core::collection::{
album::{Album, AlbumId, AlbumInfo, AlbumMeta, AlbumPrimaryType, AlbumSeq}, album::{Album, AlbumId, AlbumInfo, AlbumLibId, AlbumMeta, AlbumPrimaryType, AlbumSeq},
artist::{Artist, ArtistId, ArtistInfo, ArtistMeta}, artist::{Artist, ArtistId, ArtistInfo, ArtistMeta},
musicbrainz::{MbAlbumRef, MbArtistRef, MbRefOption}, musicbrainz::{MbAlbumRef, MbArtistRef, MbRefOption},
track::{Track, TrackFormat, TrackId, TrackNum, TrackQuality}, track::{Track, TrackFormat, TrackId, TrackNum, TrackQuality},

View File

@ -1,5 +1,5 @@
pub static DATABASE_JSON: &str = "{\ pub static DATABASE_JSON: &str = "{\
\"V20240924\":\ \"V20250101\":\
[\ [\
{\ {\
\"name\":\"Album_Artist A\",\ \"name\":\"Album_Artist A\",\
@ -11,12 +11,12 @@ pub static DATABASE_JSON: &str = "{\
},\ },\
\"albums\":[\ \"albums\":[\
{\ {\
\"title\":\"album_title a.a\",\"seq\":1,\ \"title\":\"album_title a.a\",\"lib_id\":{\"Some\":1},\"seq\":1,\
\"musicbrainz\":{\"Some\":\"00000000-0000-0000-0000-000000000000\"},\ \"musicbrainz\":{\"Some\":\"00000000-0000-0000-0000-000000000000\"},\
\"primary_type\":\"Album\",\"secondary_types\":[]\ \"primary_type\":\"Album\",\"secondary_types\":[]\
},\ },\
{\ {\
\"title\":\"album_title a.b\",\"seq\":1,\"musicbrainz\":\"None\",\ \"title\":\"album_title a.b\",\"lib_id\":{\"Some\":2},\"seq\":1,\"musicbrainz\":\"None\",\
\"primary_type\":\"Album\",\"secondary_types\":[]\ \"primary_type\":\"Album\",\"secondary_types\":[]\
}\ }\
]\ ]\
@ -35,21 +35,21 @@ pub static DATABASE_JSON: &str = "{\
},\ },\
\"albums\":[\ \"albums\":[\
{\ {\
\"title\":\"album_title b.a\",\"seq\":1,\"musicbrainz\":\"None\",\ \"title\":\"album_title b.a\",\"lib_id\":{\"Some\":3},\"seq\":1,\"musicbrainz\":\"None\",\
\"primary_type\":\"Album\",\"secondary_types\":[]\ \"primary_type\":\"Album\",\"secondary_types\":[]\
},\ },\
{\ {\
\"title\":\"album_title b.b\",\"seq\":3,\ \"title\":\"album_title b.b\",\"lib_id\":{\"Some\":4},\"seq\":3,\
\"musicbrainz\":{\"Some\":\"11111111-1111-1111-1111-111111111111\"},\ \"musicbrainz\":{\"Some\":\"11111111-1111-1111-1111-111111111111\"},\
\"primary_type\":\"Album\",\"secondary_types\":[]\ \"primary_type\":\"Album\",\"secondary_types\":[]\
},\ },\
{\ {\
\"title\":\"album_title b.c\",\"seq\":2,\ \"title\":\"album_title b.c\",\"lib_id\":{\"Some\":5},\"seq\":2,\
\"musicbrainz\":{\"Some\":\"11111111-1111-1111-1111-111111111112\"},\ \"musicbrainz\":{\"Some\":\"11111111-1111-1111-1111-111111111112\"},\
\"primary_type\":\"Album\",\"secondary_types\":[]\ \"primary_type\":\"Album\",\"secondary_types\":[]\
},\ },\
{\ {\
\"title\":\"album_title b.d\",\"seq\":4,\"musicbrainz\":\"None\",\ \"title\":\"album_title b.d\",\"lib_id\":{\"Some\":6},\"seq\":4,\"musicbrainz\":\"None\",\
\"primary_type\":\"Album\",\"secondary_types\":[]\ \"primary_type\":\"Album\",\"secondary_types\":[]\
}\ }\
]\ ]\
@ -61,11 +61,11 @@ pub static DATABASE_JSON: &str = "{\
\"properties\":{},\ \"properties\":{},\
\"albums\":[\ \"albums\":[\
{\ {\
\"title\":\"album_title c.a\",\"seq\":0,\"musicbrainz\":\"None\",\ \"title\":\"album_title c.a\",\"lib_id\":{\"Some\":7},\"seq\":0,\"musicbrainz\":\"None\",\
\"primary_type\":\"Album\",\"secondary_types\":[]\ \"primary_type\":\"Album\",\"secondary_types\":[]\
},\ },\
{\ {\
\"title\":\"album_title c.b\",\"seq\":0,\"musicbrainz\":\"None\",\ \"title\":\"album_title c.b\",\"lib_id\":{\"Some\":8},\"seq\":0,\"musicbrainz\":\"None\",\
\"primary_type\":\"Album\",\"secondary_types\":[]\ \"primary_type\":\"Album\",\"secondary_types\":[]\
}\ }\
]\ ]\
@ -77,11 +77,11 @@ pub static DATABASE_JSON: &str = "{\
\"properties\":{},\ \"properties\":{},\
\"albums\":[\ \"albums\":[\
{\ {\
\"title\":\"album_title d.a\",\"seq\":0,\"musicbrainz\":\"None\",\ \"title\":\"album_title d.a\",\"lib_id\":{\"Some\":9},\"seq\":0,\"musicbrainz\":\"None\",\
\"primary_type\":\"Album\",\"secondary_types\":[]\ \"primary_type\":\"Album\",\"secondary_types\":[]\
},\ },\
{\ {\
\"title\":\"album_title d.b\",\"seq\":0,\"musicbrainz\":\"None\",\ \"title\":\"album_title d.b\",\"lib_id\":{\"Some\":10},\"seq\":0,\"musicbrainz\":\"None\",\
\"primary_type\":\"Album\",\"secondary_types\":[]\ \"primary_type\":\"Album\",\"secondary_types\":[]\
}\ }\
]\ ]\

View File

@ -2,9 +2,17 @@ use serde::{Deserialize, Serialize};
use crate::{ use crate::{
collection::musicbrainz::MbRefOption, collection::musicbrainz::MbRefOption,
core::collection::album::{AlbumPrimaryType, AlbumSecondaryType}, core::collection::album::{AlbumLibId, AlbumPrimaryType, AlbumSecondaryType},
}; };
#[derive(Debug, Deserialize, Serialize)]
#[serde(remote = "AlbumLibId")]
pub enum AlbumLibIdDef {
Some(u32),
Singleton,
None,
}
#[derive(Debug, Deserialize, Serialize)] #[derive(Debug, Deserialize, Serialize)]
#[serde(remote = "MbRefOption")] #[serde(remote = "MbRefOption")]
pub enum MbRefOptionDef<T> { pub enum MbRefOptionDef<T> {

View File

@ -4,7 +4,7 @@ use serde::{de::Visitor, Deserialize, Deserializer};
use crate::{ use crate::{
collection::{ collection::{
album::{AlbumInfo, AlbumMeta}, album::{AlbumInfo, AlbumLibId, AlbumMeta},
artist::{ArtistInfo, ArtistMeta}, artist::{ArtistInfo, ArtistMeta},
musicbrainz::{MbAlbumRef, MbArtistRef, MbRefOption, Mbid}, musicbrainz::{MbAlbumRef, MbArtistRef, MbRefOption, Mbid},
}, },
@ -129,7 +129,10 @@ impl From<DeserializeAlbum> for Album {
fn from(album: DeserializeAlbum) -> Self { fn from(album: DeserializeAlbum) -> Self {
Album { Album {
meta: AlbumMeta { meta: AlbumMeta {
id: AlbumId { title: album.title }, id: AlbumId {
title: album.title,
lib_id: AlbumLibId::None,
},
date: AlbumDate::default(), date: AlbumDate::default(),
seq: AlbumSeq(album.seq), seq: AlbumSeq(album.seq),
info: AlbumInfo { info: AlbumInfo {

View File

@ -3,21 +3,24 @@ use std::collections::BTreeMap;
use serde::Serialize; use serde::Serialize;
use crate::{ use crate::{
collection::musicbrainz::{MbRefOption, Mbid}, collection::{
album::AlbumLibId,
musicbrainz::{MbRefOption, Mbid},
},
core::collection::{album::Album, artist::Artist, musicbrainz::IMusicBrainzRef, Collection}, core::collection::{album::Album, artist::Artist, musicbrainz::IMusicBrainzRef, Collection},
external::database::serde::common::{ external::database::serde::common::{
MbRefOptionDef, SerdeAlbumPrimaryType, SerdeAlbumSecondaryType, AlbumLibIdDef, MbRefOptionDef, SerdeAlbumPrimaryType, SerdeAlbumSecondaryType,
}, },
}; };
#[derive(Debug, Serialize)] #[derive(Debug, Serialize)]
pub enum SerializeDatabase<'a> { pub enum SerializeDatabase<'a> {
V20240924(Vec<SerializeArtist<'a>>), V20250101(Vec<SerializeArtist<'a>>),
} }
impl<'a> From<&'a Collection> for SerializeDatabase<'a> { impl<'a> From<&'a Collection> for SerializeDatabase<'a> {
fn from(collection: &'a Collection) -> Self { fn from(collection: &'a Collection) -> Self {
SerializeDatabase::V20240924(collection.iter().map(Into::into).collect()) SerializeDatabase::V20250101(collection.iter().map(Into::into).collect())
} }
} }
@ -33,12 +36,22 @@ pub struct SerializeArtist<'a> {
#[derive(Debug, Serialize)] #[derive(Debug, Serialize)]
pub struct SerializeAlbum<'a> { pub struct SerializeAlbum<'a> {
title: &'a str, title: &'a str,
lib_id: SerializeAlbumLibId,
seq: u8, seq: u8,
musicbrainz: SerializeMbRefOption<'a>, musicbrainz: SerializeMbRefOption<'a>,
primary_type: Option<SerdeAlbumPrimaryType>, primary_type: Option<SerdeAlbumPrimaryType>,
secondary_types: Vec<SerdeAlbumSecondaryType>, secondary_types: Vec<SerdeAlbumSecondaryType>,
} }
#[derive(Debug, Serialize)]
pub struct SerializeAlbumLibId(#[serde(with = "AlbumLibIdDef")] AlbumLibId);
impl From<AlbumLibId> for SerializeAlbumLibId {
fn from(value: AlbumLibId) -> Self {
SerializeAlbumLibId(value)
}
}
#[derive(Debug, Serialize)] #[derive(Debug, Serialize)]
pub struct SerializeMbRefOption<'a>( pub struct SerializeMbRefOption<'a>(
#[serde(with = "MbRefOptionDef")] MbRefOption<SerializeMbid<'a>>, #[serde(with = "MbRefOptionDef")] MbRefOption<SerializeMbid<'a>>,
@ -90,6 +103,7 @@ impl<'a> From<&'a Album> for SerializeAlbum<'a> {
fn from(album: &'a Album) -> Self { fn from(album: &'a Album) -> Self {
SerializeAlbum { SerializeAlbum {
title: &album.meta.id.title, title: &album.meta.id.title,
lib_id: album.meta.id.lib_id.into(),
seq: album.meta.seq.0, seq: album.meta.seq.0,
musicbrainz: (&album.meta.info.musicbrainz).into(), musicbrainz: (&album.meta.info.musicbrainz).into(),
primary_type: album.meta.info.primary_type.map(Into::into), primary_type: album.meta.info.primary_type.map(Into::into),

View File

@ -28,6 +28,7 @@ macro_rules! full_collection {
meta: AlbumMeta { meta: AlbumMeta {
id: AlbumId { id: AlbumId {
title: "album_title a.a".to_string(), title: "album_title a.a".to_string(),
lib_id: AlbumLibId::Some(1),
}, },
date: 1998.into(), date: 1998.into(),
seq: AlbumSeq(1), seq: AlbumSeq(1),
@ -93,6 +94,7 @@ macro_rules! full_collection {
meta: AlbumMeta { meta: AlbumMeta {
id: AlbumId { id: AlbumId {
title: "album_title a.b".to_string(), title: "album_title a.b".to_string(),
lib_id: AlbumLibId::Some(2),
}, },
date: (2015, 4).into(), date: (2015, 4).into(),
seq: AlbumSeq(1), seq: AlbumSeq(1),
@ -160,6 +162,7 @@ macro_rules! full_collection {
meta: AlbumMeta { meta: AlbumMeta {
id: AlbumId { id: AlbumId {
title: "album_title b.a".to_string(), title: "album_title b.a".to_string(),
lib_id: AlbumLibId::Some(3),
}, },
date: (2003, 6, 6).into(), date: (2003, 6, 6).into(),
seq: AlbumSeq(1), seq: AlbumSeq(1),
@ -201,6 +204,7 @@ macro_rules! full_collection {
meta: AlbumMeta { meta: AlbumMeta {
id: AlbumId { id: AlbumId {
title: "album_title b.b".to_string(), title: "album_title b.b".to_string(),
lib_id: AlbumLibId::Some(4),
}, },
date: 2008.into(), date: 2008.into(),
seq: AlbumSeq(3), seq: AlbumSeq(3),
@ -244,6 +248,7 @@ macro_rules! full_collection {
meta: AlbumMeta { meta: AlbumMeta {
id: AlbumId { id: AlbumId {
title: "album_title b.c".to_string(), title: "album_title b.c".to_string(),
lib_id: AlbumLibId::Some(5),
}, },
date: 2009.into(), date: 2009.into(),
seq: AlbumSeq(2), seq: AlbumSeq(2),
@ -287,6 +292,7 @@ macro_rules! full_collection {
meta: AlbumMeta { meta: AlbumMeta {
id: AlbumId { id: AlbumId {
title: "album_title b.d".to_string(), title: "album_title b.d".to_string(),
lib_id: AlbumLibId::Some(6),
}, },
date: 2015.into(), date: 2015.into(),
seq: AlbumSeq(4), seq: AlbumSeq(4),
@ -342,6 +348,7 @@ macro_rules! full_collection {
meta: AlbumMeta { meta: AlbumMeta {
id: AlbumId { id: AlbumId {
title: "album_title c.a".to_string(), title: "album_title c.a".to_string(),
lib_id: AlbumLibId::Some(7),
}, },
date: 1985.into(), date: 1985.into(),
seq: AlbumSeq(0), seq: AlbumSeq(0),
@ -383,6 +390,7 @@ macro_rules! full_collection {
meta: AlbumMeta { meta: AlbumMeta {
id: AlbumId { id: AlbumId {
title: "album_title c.b".to_string(), title: "album_title c.b".to_string(),
lib_id: AlbumLibId::Some(8),
}, },
date: 2018.into(), date: 2018.into(),
seq: AlbumSeq(0), seq: AlbumSeq(0),
@ -438,6 +446,7 @@ macro_rules! full_collection {
meta: AlbumMeta { meta: AlbumMeta {
id: AlbumId { id: AlbumId {
title: "album_title d.a".to_string(), title: "album_title d.a".to_string(),
lib_id: AlbumLibId::Some(9),
}, },
date: 1995.into(), date: 1995.into(),
seq: AlbumSeq(0), seq: AlbumSeq(0),
@ -479,6 +488,7 @@ macro_rules! full_collection {
meta: AlbumMeta { meta: AlbumMeta {
id: AlbumId { id: AlbumId {
title: "album_title d.b".to_string(), title: "album_title d.b".to_string(),
lib_id: AlbumLibId::Some(10),
}, },
date: 2028.into(), date: 2028.into(),
seq: AlbumSeq(0), seq: AlbumSeq(0),

View File

@ -18,6 +18,7 @@ macro_rules! library_collection {
meta: AlbumMeta { meta: AlbumMeta {
id: AlbumId { id: AlbumId {
title: "album_title a.a".to_string(), title: "album_title a.a".to_string(),
lib_id: AlbumLibId::Some(1),
}, },
date: 1998.into(), date: 1998.into(),
seq: AlbumSeq(0), seq: AlbumSeq(0),
@ -77,6 +78,7 @@ macro_rules! library_collection {
meta: AlbumMeta { meta: AlbumMeta {
id: AlbumId { id: AlbumId {
title: "album_title a.b".to_string(), title: "album_title a.b".to_string(),
lib_id: AlbumLibId::Some(2),
}, },
date: (2015, 4).into(), date: (2015, 4).into(),
seq: AlbumSeq(0), seq: AlbumSeq(0),
@ -125,6 +127,7 @@ macro_rules! library_collection {
meta: AlbumMeta { meta: AlbumMeta {
id: AlbumId { id: AlbumId {
title: "album_title b.a".to_string(), title: "album_title b.a".to_string(),
lib_id: AlbumLibId::Some(3),
}, },
date: (2003, 6, 6).into(), date: (2003, 6, 6).into(),
seq: AlbumSeq(0), seq: AlbumSeq(0),
@ -162,6 +165,7 @@ macro_rules! library_collection {
meta: AlbumMeta { meta: AlbumMeta {
id: AlbumId { id: AlbumId {
title: "album_title b.b".to_string(), title: "album_title b.b".to_string(),
lib_id: AlbumLibId::Some(4),
}, },
date: 2008.into(), date: 2008.into(),
seq: AlbumSeq(0), seq: AlbumSeq(0),
@ -199,6 +203,7 @@ macro_rules! library_collection {
meta: AlbumMeta { meta: AlbumMeta {
id: AlbumId { id: AlbumId {
title: "album_title b.c".to_string(), title: "album_title b.c".to_string(),
lib_id: AlbumLibId::Some(5),
}, },
date: 2009.into(), date: 2009.into(),
seq: AlbumSeq(0), seq: AlbumSeq(0),
@ -236,6 +241,7 @@ macro_rules! library_collection {
meta: AlbumMeta { meta: AlbumMeta {
id: AlbumId { id: AlbumId {
title: "album_title b.d".to_string(), title: "album_title b.d".to_string(),
lib_id: AlbumLibId::Some(6),
}, },
date: 2015.into(), date: 2015.into(),
seq: AlbumSeq(0), seq: AlbumSeq(0),
@ -287,6 +293,7 @@ macro_rules! library_collection {
meta: AlbumMeta { meta: AlbumMeta {
id: AlbumId { id: AlbumId {
title: "album_title c.a".to_string(), title: "album_title c.a".to_string(),
lib_id: AlbumLibId::Some(7),
}, },
date: 1985.into(), date: 1985.into(),
seq: AlbumSeq(0), seq: AlbumSeq(0),
@ -324,6 +331,7 @@ macro_rules! library_collection {
meta: AlbumMeta { meta: AlbumMeta {
id: AlbumId { id: AlbumId {
title: "album_title c.b".to_string(), title: "album_title c.b".to_string(),
lib_id: AlbumLibId::Some(8),
}, },
date: 2018.into(), date: 2018.into(),
seq: AlbumSeq(0), seq: AlbumSeq(0),
@ -375,6 +383,7 @@ macro_rules! library_collection {
meta: AlbumMeta { meta: AlbumMeta {
id: AlbumId { id: AlbumId {
title: "album_title d.a".to_string(), title: "album_title d.a".to_string(),
lib_id: AlbumLibId::Some(9),
}, },
date: 1995.into(), date: 1995.into(),
seq: AlbumSeq(0), seq: AlbumSeq(0),
@ -412,6 +421,7 @@ macro_rules! library_collection {
meta: AlbumMeta { meta: AlbumMeta {
id: AlbumId { id: AlbumId {
title: "album_title d.b".to_string(), title: "album_title d.b".to_string(),
lib_id: AlbumLibId::Some(10),
}, },
date: 2028.into(), date: 2028.into(),
seq: AlbumSeq(0), seq: AlbumSeq(0),

View File

@ -1,7 +1,7 @@
use std::collections::HashMap; use std::collections::HashMap;
use musichoard::collection::{ use musichoard::collection::{
album::{Album, AlbumId, AlbumInfo, AlbumMeta, AlbumPrimaryType, AlbumSeq}, album::{Album, AlbumId, AlbumInfo, AlbumLibId, AlbumMeta, AlbumPrimaryType, AlbumSeq},
artist::{Artist, ArtistId, ArtistInfo, ArtistMeta}, artist::{Artist, ArtistId, ArtistInfo, ArtistMeta},
musicbrainz::{MbAlbumRef, MbArtistRef, MbRefOption}, musicbrainz::{MbAlbumRef, MbArtistRef, MbRefOption},
track::{Track, TrackFormat, TrackId, TrackNum, TrackQuality}, track::{Track, TrackFormat, TrackId, TrackNum, TrackQuality},

View File

@ -1,6 +1,6 @@
use musichoard::collection::{ use musichoard::collection::{
album::{ album::{
AlbumDate, AlbumId, AlbumMeta, AlbumPrimaryType, AlbumSecondaryType, AlbumSeq, AlbumStatus, AlbumDate, AlbumId, AlbumLibId, AlbumMeta, AlbumPrimaryType, AlbumSecondaryType, AlbumSeq, AlbumStatus
}, },
artist::ArtistMeta, artist::ArtistMeta,
musicbrainz::{IMusicBrainzRef, MbRefOption}, musicbrainz::{IMusicBrainzRef, MbRefOption},
@ -20,6 +20,14 @@ impl UiDisplay {
} }
} }
pub fn display_album_lib_id(lib_id: &AlbumLibId) -> String {
match lib_id {
AlbumLibId::Some(val) => val.to_string(),
AlbumLibId::Singleton => "Singleton".to_string(),
AlbumLibId::None => "None".to_string(),
}
}
pub fn display_album_date(date: &AlbumDate) -> String { pub fn display_album_date(date: &AlbumDate) -> String {
match date.year { match date.year {
Some(year) => match date.month { Some(year) => match date.month {

View File

@ -101,8 +101,12 @@ impl<'a> AlbumOverlay<'a> {
let properties = Paragraph::new(format!( let properties = Paragraph::new(format!(
"Album: {}\n\n{item_indent}\ "Album: {}\n\n{item_indent}\
Library ID: {}\n{item_indent}\
MusicBrainz: {}", MusicBrainz: {}",
album.map(|a| a.meta.id.title.as_str()).unwrap_or(""), album.map(|a| a.meta.id.title.as_str()).unwrap_or(""),
album
.map(|a| UiDisplay::display_album_lib_id(&a.meta.id.lib_id))
.unwrap_or_default(),
album 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.info.musicbrainz))
.unwrap_or_default(), .unwrap_or_default(),

View File

@ -2,7 +2,10 @@ use once_cell::sync::Lazy;
use std::collections::HashMap; use std::collections::HashMap;
use musichoard::collection::{ use musichoard::collection::{
album::{Album, AlbumId, AlbumInfo, AlbumMeta, AlbumPrimaryType, AlbumSecondaryType, AlbumSeq}, album::{
Album, AlbumId, AlbumInfo, AlbumLibId, AlbumMeta, AlbumPrimaryType, AlbumSecondaryType,
AlbumSeq,
},
artist::{Artist, ArtistId, ArtistInfo, ArtistMeta}, artist::{Artist, ArtistId, ArtistInfo, ArtistMeta},
musicbrainz::{MbArtistRef, MbRefOption}, musicbrainz::{MbArtistRef, MbRefOption},
track::{Track, TrackFormat, TrackId, TrackNum, TrackQuality}, track::{Track, TrackFormat, TrackId, TrackNum, TrackQuality},
@ -38,6 +41,7 @@ pub static COLLECTION: Lazy<Vec<Artist>> = Lazy::new(|| -> Collection {
meta: AlbumMeta { meta: AlbumMeta {
id: AlbumId { id: AlbumId {
title: String::from("Slovo"), title: String::from("Slovo"),
lib_id: AlbumLibId::Some(7),
}, },
date: 2011.into(), date: 2011.into(),
seq: AlbumSeq(0), seq: AlbumSeq(0),
@ -230,6 +234,7 @@ pub static COLLECTION: Lazy<Vec<Artist>> = Lazy::new(|| -> Collection {
meta: AlbumMeta { meta: AlbumMeta {
id: AlbumId { id: AlbumId {
title: String::from("Vên [rerecorded]"), title: String::from("Vên [rerecorded]"),
lib_id: AlbumLibId::Some(1),
}, },
date: 2004.into(), date: 2004.into(),
seq: AlbumSeq(0), seq: AlbumSeq(0),
@ -312,6 +317,7 @@ pub static COLLECTION: Lazy<Vec<Artist>> = Lazy::new(|| -> Collection {
meta: AlbumMeta { meta: AlbumMeta {
id: AlbumId { id: AlbumId {
title: String::from("Slania"), title: String::from("Slania"),
lib_id: AlbumLibId::Some(2),
}, },
date: 2008.into(), date: 2008.into(),
seq: AlbumSeq(0), seq: AlbumSeq(0),
@ -482,6 +488,7 @@ pub static COLLECTION: Lazy<Vec<Artist>> = Lazy::new(|| -> Collection {
meta: AlbumMeta { meta: AlbumMeta {
id: AlbumId { id: AlbumId {
title: String::from("…nasze jest królestwo, potęga i chwała na wieki…"), title: String::from("…nasze jest królestwo, potęga i chwała na wieki…"),
lib_id: AlbumLibId::Some(3),
}, },
date: 2001.into(), date: 2001.into(),
seq: AlbumSeq(0), seq: AlbumSeq(0),
@ -640,6 +647,7 @@ pub static COLLECTION: Lazy<Vec<Artist>> = Lazy::new(|| -> Collection {
meta: AlbumMeta { meta: AlbumMeta {
id: AlbumId { id: AlbumId {
title: String::from("Paper Plague"), title: String::from("Paper Plague"),
lib_id: AlbumLibId::Singleton,
}, },
date: 2011.into(), date: 2011.into(),
seq: AlbumSeq(0), seq: AlbumSeq(0),
@ -662,6 +670,7 @@ pub static COLLECTION: Lazy<Vec<Artist>> = Lazy::new(|| -> Collection {
meta: AlbumMeta { meta: AlbumMeta {
id: AlbumId { id: AlbumId {
title: String::from("Unbreakable"), title: String::from("Unbreakable"),
lib_id: AlbumLibId::Some(4),
}, },
date: 2011.into(), date: 2011.into(),
seq: AlbumSeq(0), seq: AlbumSeq(0),
@ -777,6 +786,7 @@ pub static COLLECTION: Lazy<Vec<Artist>> = Lazy::new(|| -> Collection {
meta: AlbumMeta { meta: AlbumMeta {
id: AlbumId { id: AlbumId {
title: String::from("Ride the Lightning"), title: String::from("Ride the Lightning"),
lib_id: AlbumLibId::Some(5),
}, },
date: 1984.into(), date: 1984.into(),
seq: AlbumSeq(0), seq: AlbumSeq(0),
@ -881,6 +891,7 @@ pub static COLLECTION: Lazy<Vec<Artist>> = Lazy::new(|| -> Collection {
meta: AlbumMeta { meta: AlbumMeta {
id: AlbumId { id: AlbumId {
title: String::from("S&M"), title: String::from("S&M"),
lib_id: AlbumLibId::Some(6),
}, },
date: 1999.into(), date: 1999.into(),
seq: AlbumSeq(0), seq: AlbumSeq(0),