Sort albums by month if two releases of the same artist happen in the same year #155
@ -118,6 +118,12 @@ impl Merge for Album {
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Into<String>> From<S> for AlbumId {
|
||||
fn from(value: S) -> Self {
|
||||
AlbumId::new(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<AlbumId> for AlbumId {
|
||||
fn as_ref(&self) -> &AlbumId {
|
||||
self
|
||||
@ -193,6 +199,32 @@ mod tests {
|
||||
assert!(album_1 < album_2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_clear_seq() {
|
||||
let mut album = Album {
|
||||
id: "an album".into(),
|
||||
date: AlbumDate::default(),
|
||||
seq: AlbumSeq::default(),
|
||||
tracks: vec![],
|
||||
};
|
||||
|
||||
assert_eq!(album.seq, AlbumSeq(0));
|
||||
|
||||
// Setting a seq on an album.
|
||||
album.set_seq(AlbumSeq(6));
|
||||
assert_eq!(album.seq, AlbumSeq(6));
|
||||
|
||||
album.set_seq(AlbumSeq(6));
|
||||
assert_eq!(album.seq, AlbumSeq(6));
|
||||
|
||||
album.set_seq(AlbumSeq(8));
|
||||
assert_eq!(album.seq, AlbumSeq(8));
|
||||
|
||||
// Clearing seq.
|
||||
album.clear_seq();
|
||||
assert_eq!(album.seq, AlbumSeq(0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn merge_album_no_overlap() {
|
||||
let left = FULL_COLLECTION[0].albums[0].to_owned();
|
||||
|
@ -2,6 +2,7 @@ use std::{
|
||||
collections::HashMap,
|
||||
fmt::{self, Debug, Display},
|
||||
mem,
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
use url::Url;
|
||||
@ -139,6 +140,12 @@ impl Merge for Artist {
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Into<String>> From<S> for ArtistId {
|
||||
fn from(value: S) -> Self {
|
||||
ArtistId::new(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<ArtistId> for ArtistId {
|
||||
fn as_ref(&self) -> &ArtistId {
|
||||
self
|
||||
@ -169,9 +176,13 @@ pub struct MusicBrainz(Url);
|
||||
|
||||
impl MusicBrainz {
|
||||
/// Validate and wrap a MusicBrainz URL.
|
||||
pub fn new<S: AsRef<str>>(url: S) -> Result<Self, Error> {
|
||||
pub fn new_from_str<S: AsRef<str>>(url: S) -> Result<Self, Error> {
|
||||
let url = Url::parse(url.as_ref())?;
|
||||
Self::new_from_url(url)
|
||||
}
|
||||
|
||||
/// Validate and wrap a MusicBrainz URL.
|
||||
pub fn new_from_url(url: Url) -> Result<Self, Error> {
|
||||
if !url
|
||||
.domain()
|
||||
.map(|u| u.ends_with("musicbrainz.org"))
|
||||
@ -199,11 +210,36 @@ impl AsRef<str> for MusicBrainz {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&str> for MusicBrainz {
|
||||
impl FromStr for MusicBrainz {
|
||||
type Err = Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
MusicBrainz::new_from_str(s)
|
||||
}
|
||||
}
|
||||
|
||||
// A blanket TryFrom would be better, but https://stackoverflow.com/a/64407892
|
||||
macro_rules! impl_try_from_for_musicbrainz {
|
||||
($from:ty) => {
|
||||
impl TryFrom<$from> for MusicBrainz {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from(value: &str) -> Result<Self, Self::Error> {
|
||||
MusicBrainz::new(value)
|
||||
fn try_from(value: $from) -> Result<Self, Self::Error> {
|
||||
MusicBrainz::new_from_str(value)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_try_from_for_musicbrainz!(&str);
|
||||
impl_try_from_for_musicbrainz!(&String);
|
||||
impl_try_from_for_musicbrainz!(String);
|
||||
|
||||
impl TryFrom<Url> for MusicBrainz {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from(value: Url) -> Result<Self, Self::Error> {
|
||||
MusicBrainz::new_from_url(value)
|
||||
}
|
||||
}
|
||||
|
||||
@ -230,34 +266,35 @@ mod tests {
|
||||
#[test]
|
||||
fn musicbrainz() {
|
||||
let uuid = "d368baa8-21ca-4759-9731-0b2753071ad8";
|
||||
let url = format!("https://musicbrainz.org/artist/{uuid}");
|
||||
let mb = MusicBrainz::new(&url).unwrap();
|
||||
assert_eq!(url, mb.as_ref());
|
||||
let url_str = format!("https://musicbrainz.org/artist/{uuid}");
|
||||
let url: Url = url_str.as_str().try_into().unwrap();
|
||||
let mb: MusicBrainz = url.try_into().unwrap();
|
||||
assert_eq!(url_str, mb.as_ref());
|
||||
assert_eq!(uuid, mb.mbid());
|
||||
|
||||
let url = "not a url at all".to_string();
|
||||
let expected_error: Error = url::ParseError::RelativeUrlWithoutBase.into();
|
||||
let actual_error = MusicBrainz::new(url).unwrap_err();
|
||||
let actual_error = MusicBrainz::from_str(&url).unwrap_err();
|
||||
assert_eq!(actual_error, expected_error);
|
||||
assert_eq!(actual_error.to_string(), expected_error.to_string());
|
||||
|
||||
let url = "https://musicbrainz.org/artist/i-am-not-a-uuid".to_string();
|
||||
let expected_error: Error = Uuid::try_parse("i-am-not-a-uuid").unwrap_err().into();
|
||||
let actual_error = MusicBrainz::new(url).unwrap_err();
|
||||
let actual_error = MusicBrainz::from_str(&url).unwrap_err();
|
||||
assert_eq!(actual_error, expected_error);
|
||||
assert_eq!(actual_error.to_string(), expected_error.to_string());
|
||||
|
||||
let url = "https://musicbrainz.org/artist".to_string();
|
||||
let expected_error = Error::UrlError(format!("invalid MusicBrainz URL: {url}"));
|
||||
let actual_error = MusicBrainz::new(&url).unwrap_err();
|
||||
let actual_error = MusicBrainz::from_str(&url).unwrap_err();
|
||||
assert_eq!(actual_error, expected_error);
|
||||
assert_eq!(actual_error.to_string(), expected_error.to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn urls() {
|
||||
assert!(MusicBrainz::new(MUSICBRAINZ).is_ok());
|
||||
assert!(MusicBrainz::new(MUSICBUTLER).is_err());
|
||||
assert!(MusicBrainz::from_str(MUSICBRAINZ).is_ok());
|
||||
assert!(MusicBrainz::from_str(MUSICBUTLER).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -266,7 +303,7 @@ mod tests {
|
||||
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.clone());
|
||||
let mut artist = Artist::new(&artist_id.name);
|
||||
|
||||
assert_eq!(artist.id, artist_id);
|
||||
assert_eq!(artist.sort, None);
|
||||
@ -317,14 +354,14 @@ mod tests {
|
||||
|
||||
// Setting a URL on an artist.
|
||||
artist.set_musicbrainz_url(MUSICBRAINZ.try_into().unwrap());
|
||||
_ = expected.insert(MusicBrainz::new(MUSICBRAINZ).unwrap());
|
||||
_ = expected.insert(MUSICBRAINZ.try_into().unwrap());
|
||||
assert_eq!(artist.musicbrainz, expected);
|
||||
|
||||
artist.set_musicbrainz_url(MUSICBRAINZ.try_into().unwrap());
|
||||
assert_eq!(artist.musicbrainz, expected);
|
||||
|
||||
artist.set_musicbrainz_url(MUSICBRAINZ_2.try_into().unwrap());
|
||||
_ = expected.insert(MusicBrainz::new(MUSICBRAINZ_2).unwrap());
|
||||
_ = expected.insert(MUSICBRAINZ_2.try_into().unwrap());
|
||||
assert_eq!(artist.musicbrainz, expected);
|
||||
|
||||
// Clearing URLs.
|
||||
|
@ -5,7 +5,7 @@ use serde::Deserialize;
|
||||
use crate::core::{
|
||||
collection::{
|
||||
album::{Album, AlbumDate, AlbumId, AlbumSeq},
|
||||
artist::{Artist, ArtistId, MusicBrainz},
|
||||
artist::{Artist, ArtistId},
|
||||
Collection,
|
||||
},
|
||||
database::LoadError,
|
||||
@ -51,7 +51,7 @@ impl TryFrom<DeserializeArtist> for Artist {
|
||||
Ok(Artist {
|
||||
id: ArtistId::new(artist.name),
|
||||
sort: artist.sort.map(ArtistId::new),
|
||||
musicbrainz: artist.musicbrainz.map(MusicBrainz::new).transpose()?,
|
||||
musicbrainz: artist.musicbrainz.map(TryInto::try_into).transpose()?,
|
||||
properties: artist.properties,
|
||||
albums: artist.albums.into_iter().map(Into::into).collect(),
|
||||
})
|
||||
|
@ -3,7 +3,7 @@ use std::collections::HashMap;
|
||||
use crate::core::{
|
||||
collection::{
|
||||
album::{Album, AlbumDate, AlbumId, AlbumSeq},
|
||||
artist::{Artist, ArtistId},
|
||||
artist::{Artist, ArtistId, MusicBrainz},
|
||||
track::{Track, TrackId, TrackNum, TrackQuality},
|
||||
Collection, MergeCollections,
|
||||
},
|
||||
@ -259,63 +259,61 @@ impl<LIB, DB: IDatabase> MusicHoard<LIB, DB> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn update_collection<FN>(&mut self, func: FN) -> Result<(), Error>
|
||||
fn update_collection<FnColl>(&mut self, fn_coll: FnColl) -> Result<(), Error>
|
||||
where
|
||||
FN: FnOnce(&mut Collection),
|
||||
FnColl: FnOnce(&mut Collection),
|
||||
{
|
||||
func(&mut self.pre_commit);
|
||||
fn_coll(&mut self.pre_commit);
|
||||
self.commit()
|
||||
}
|
||||
|
||||
fn update_artist_and<ID: AsRef<ArtistId>, FNARTIST, FNCOLL>(
|
||||
fn update_artist_and<FnArtist, FnColl>(
|
||||
&mut self,
|
||||
artist_id: ID,
|
||||
fn_artist: FNARTIST,
|
||||
fn_collection: FNCOLL,
|
||||
artist_id: &ArtistId,
|
||||
fn_artist: FnArtist,
|
||||
fn_coll: FnColl,
|
||||
) -> Result<(), Error>
|
||||
where
|
||||
FNARTIST: FnOnce(&mut Artist),
|
||||
FNCOLL: FnOnce(&mut Collection),
|
||||
FnArtist: FnOnce(&mut Artist),
|
||||
FnColl: FnOnce(&mut Collection),
|
||||
{
|
||||
fn_artist(Self::get_artist_mut_or_err(
|
||||
&mut self.pre_commit,
|
||||
artist_id.as_ref(),
|
||||
)?);
|
||||
self.update_collection(fn_collection)
|
||||
let artist = Self::get_artist_mut_or_err(&mut self.pre_commit, artist_id)?;
|
||||
fn_artist(artist);
|
||||
self.update_collection(fn_coll)
|
||||
}
|
||||
|
||||
fn update_artist<ID: AsRef<ArtistId>, FN>(
|
||||
fn update_artist<FnArtist>(
|
||||
&mut self,
|
||||
artist_id: ID,
|
||||
func: FN,
|
||||
artist_id: &ArtistId,
|
||||
fn_artist: FnArtist,
|
||||
) -> Result<(), Error>
|
||||
where
|
||||
FN: FnOnce(&mut Artist),
|
||||
FnArtist: FnOnce(&mut Artist),
|
||||
{
|
||||
self.update_artist_and(artist_id, func, |_| {})
|
||||
self.update_artist_and(artist_id, fn_artist, |_| {})
|
||||
}
|
||||
|
||||
fn update_album_and<ARTIST: AsRef<ArtistId>, ALBUM: AsRef<AlbumId>, FNALBUM, FNARTIST, FNCOLL>(
|
||||
fn update_album_and<FnAlbum, FnArtist, FnColl>(
|
||||
&mut self,
|
||||
artist_id: ARTIST,
|
||||
album_id: ALBUM,
|
||||
fn_album: FNALBUM,
|
||||
fn_artist: FNARTIST,
|
||||
fn_collection: FNCOLL,
|
||||
artist_id: &ArtistId,
|
||||
album_id: &AlbumId,
|
||||
fn_album: FnAlbum,
|
||||
fn_artist: FnArtist,
|
||||
fn_coll: FnColl,
|
||||
) -> Result<(), Error>
|
||||
where
|
||||
FNALBUM: FnOnce(&mut Album),
|
||||
FNARTIST: FnOnce(&mut Artist),
|
||||
FNCOLL: FnOnce(&mut Collection),
|
||||
FnAlbum: FnOnce(&mut Album),
|
||||
FnArtist: FnOnce(&mut Artist),
|
||||
FnColl: FnOnce(&mut Collection),
|
||||
{
|
||||
let artist = Self::get_artist_mut_or_err(&mut self.pre_commit, artist_id.as_ref())?;
|
||||
let album = Self::get_album_mut_or_err(artist, album_id.as_ref())?;
|
||||
let artist = Self::get_artist_mut_or_err(&mut self.pre_commit, artist_id)?;
|
||||
let album = Self::get_album_mut_or_err(artist, album_id)?;
|
||||
fn_album(album);
|
||||
fn_artist(artist);
|
||||
self.update_collection(fn_collection)
|
||||
self.update_collection(fn_coll)
|
||||
}
|
||||
|
||||
pub fn add_artist<ID: Into<ArtistId>>(&mut self, artist_id: ID) -> Result<(), Error> {
|
||||
pub fn add_artist<IntoId: Into<ArtistId>>(&mut self, artist_id: IntoId) -> Result<(), Error> {
|
||||
let artist_id: ArtistId = artist_id.into();
|
||||
|
||||
self.update_collection(|collection| {
|
||||
@ -326,7 +324,7 @@ impl<LIB, DB: IDatabase> MusicHoard<LIB, DB> {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn remove_artist<ID: AsRef<ArtistId>>(&mut self, artist_id: ID) -> Result<(), Error> {
|
||||
pub fn remove_artist<Id: AsRef<ArtistId>>(&mut self, artist_id: Id) -> Result<(), Error> {
|
||||
self.update_collection(|collection| {
|
||||
let index_opt = collection.iter().position(|a| &a.id == artist_id.as_ref());
|
||||
if let Some(index) = index_opt {
|
||||
@ -335,102 +333,109 @@ impl<LIB, DB: IDatabase> MusicHoard<LIB, DB> {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn set_artist_sort<ID: AsRef<ArtistId>, SORT: Into<ArtistId>>(
|
||||
pub fn set_artist_sort<Id: AsRef<ArtistId>, IntoId: Into<ArtistId>>(
|
||||
&mut self,
|
||||
artist_id: ID,
|
||||
artist_sort: SORT,
|
||||
artist_id: Id,
|
||||
artist_sort: IntoId,
|
||||
) -> Result<(), Error> {
|
||||
self.update_artist_and(
|
||||
artist_id,
|
||||
artist_id.as_ref(),
|
||||
|artist| artist.set_sort_key(artist_sort),
|
||||
|collection| Self::sort_artists(collection),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn clear_artist_sort<ID: AsRef<ArtistId>>(&mut self, artist_id: ID) -> Result<(), Error> {
|
||||
pub fn clear_artist_sort<Id: AsRef<ArtistId>>(&mut self, artist_id: Id) -> Result<(), Error> {
|
||||
self.update_artist_and(
|
||||
artist_id,
|
||||
artist_id.as_ref(),
|
||||
|artist| artist.clear_sort_key(),
|
||||
|collection| Self::sort_artists(collection),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn set_artist_musicbrainz<ID: AsRef<ArtistId>, S: AsRef<str>>(
|
||||
pub fn set_artist_musicbrainz<Id: AsRef<ArtistId>, Mb: TryInto<MusicBrainz, Error = E>, E>(
|
||||
&mut self,
|
||||
artist_id: ID,
|
||||
url: S,
|
||||
) -> Result<(), Error> {
|
||||
let url = url.as_ref().try_into()?;
|
||||
self.update_artist(artist_id, |artist| artist.set_musicbrainz_url(url))
|
||||
artist_id: Id,
|
||||
url: Mb,
|
||||
) -> Result<(), Error>
|
||||
where
|
||||
Error: From<E>,
|
||||
{
|
||||
let mb = url.try_into()?;
|
||||
self.update_artist(artist_id.as_ref(), |artist| artist.set_musicbrainz_url(mb))
|
||||
}
|
||||
|
||||
pub fn clear_artist_musicbrainz<ID: AsRef<ArtistId>>(
|
||||
pub fn clear_artist_musicbrainz<Id: AsRef<ArtistId>>(
|
||||
&mut self,
|
||||
artist_id: ID,
|
||||
artist_id: Id,
|
||||
) -> Result<(), Error> {
|
||||
self.update_artist(artist_id, |artist| artist.clear_musicbrainz_url())
|
||||
self.update_artist(artist_id.as_ref(), |artist| artist.clear_musicbrainz_url())
|
||||
}
|
||||
|
||||
pub fn add_to_artist_property<ID: AsRef<ArtistId>, S: AsRef<str> + Into<String>>(
|
||||
pub fn add_to_artist_property<Id: AsRef<ArtistId>, S: AsRef<str> + Into<String>>(
|
||||
&mut self,
|
||||
artist_id: ID,
|
||||
artist_id: Id,
|
||||
property: S,
|
||||
values: Vec<S>,
|
||||
) -> Result<(), Error> {
|
||||
self.update_artist(artist_id, |artist| artist.add_to_property(property, values))
|
||||
self.update_artist(artist_id.as_ref(), |artist| {
|
||||
artist.add_to_property(property, values)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn remove_from_artist_property<ID: AsRef<ArtistId>, S: AsRef<str>>(
|
||||
pub fn remove_from_artist_property<Id: AsRef<ArtistId>, S: AsRef<str>>(
|
||||
&mut self,
|
||||
artist_id: ID,
|
||||
artist_id: Id,
|
||||
property: S,
|
||||
values: Vec<S>,
|
||||
) -> Result<(), Error> {
|
||||
self.update_artist(artist_id, |artist| {
|
||||
self.update_artist(artist_id.as_ref(), |artist| {
|
||||
artist.remove_from_property(property, values)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn set_artist_property<ID: AsRef<ArtistId>, S: AsRef<str> + Into<String>>(
|
||||
pub fn set_artist_property<Id: AsRef<ArtistId>, S: AsRef<str> + Into<String>>(
|
||||
&mut self,
|
||||
artist_id: ID,
|
||||
artist_id: Id,
|
||||
property: S,
|
||||
values: Vec<S>,
|
||||
) -> Result<(), Error> {
|
||||
self.update_artist(artist_id, |artist| artist.set_property(property, values))
|
||||
self.update_artist(artist_id.as_ref(), |artist| {
|
||||
artist.set_property(property, values)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn clear_artist_property<ID: AsRef<ArtistId>, S: AsRef<str>>(
|
||||
pub fn clear_artist_property<Id: AsRef<ArtistId>, S: AsRef<str>>(
|
||||
&mut self,
|
||||
artist_id: ID,
|
||||
artist_id: Id,
|
||||
property: S,
|
||||
) -> Result<(), Error> {
|
||||
self.update_artist(artist_id, |artist| artist.clear_property(property))
|
||||
self.update_artist(artist_id.as_ref(), |artist| artist.clear_property(property))
|
||||
}
|
||||
|
||||
pub fn set_album_seq<ARTIST: AsRef<ArtistId>, ALBUM: AsRef<AlbumId>>(
|
||||
pub fn set_album_seq<ArtistIdRef: AsRef<ArtistId>, AlbumIdRef: AsRef<AlbumId>>(
|
||||
&mut self,
|
||||
artist_id: ARTIST,
|
||||
album_id: ALBUM,
|
||||
artist_id: ArtistIdRef,
|
||||
album_id: AlbumIdRef,
|
||||
seq: u8,
|
||||
) -> Result<(), Error> {
|
||||
self.update_album_and(
|
||||
artist_id,
|
||||
album_id,
|
||||
artist_id.as_ref(),
|
||||
album_id.as_ref(),
|
||||
|album| album.set_seq(AlbumSeq(seq)),
|
||||
|artist| artist.albums.sort_unstable(),
|
||||
|_| {},
|
||||
)
|
||||
}
|
||||
|
||||
pub fn clear_album_seq<ARTIST: AsRef<ArtistId>, ALBUM: AsRef<AlbumId>>(
|
||||
pub fn clear_album_seq<ArtistIdRef: AsRef<ArtistId>, AlbumIdRef: AsRef<AlbumId>>(
|
||||
&mut self,
|
||||
artist_id: ARTIST,
|
||||
album_id: ALBUM,
|
||||
artist_id: ArtistIdRef,
|
||||
album_id: AlbumIdRef,
|
||||
) -> Result<(), Error> {
|
||||
self.update_album_and(
|
||||
artist_id,
|
||||
album_id,
|
||||
artist_id.as_ref(),
|
||||
album_id.as_ref(),
|
||||
|album| album.clear_seq(),
|
||||
|artist| artist.albums.sort_unstable(),
|
||||
|_| {},
|
||||
@ -621,7 +626,7 @@ mod tests {
|
||||
assert!(music_hoard
|
||||
.set_artist_musicbrainz(&artist_id, MUSICBRAINZ)
|
||||
.is_ok());
|
||||
_ = expected.insert(MusicBrainz::new(MUSICBRAINZ).unwrap());
|
||||
_ = expected.insert(MUSICBRAINZ.try_into().unwrap());
|
||||
assert_eq!(music_hoard.collection[0].musicbrainz, expected);
|
||||
|
||||
// Clearing URLs on an artist that does not exist is an error.
|
||||
@ -733,6 +738,51 @@ mod tests {
|
||||
assert!(music_hoard.collection[0].properties.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn set_clear_album_seq() {
|
||||
let mut database = MockIDatabase::new();
|
||||
|
||||
let artist_id = ArtistId::new("an artist");
|
||||
let album_id = AlbumId::new("an album");
|
||||
let album_id_2 = AlbumId::new("another album");
|
||||
|
||||
let mut database_result = vec![Artist::new(artist_id.clone())];
|
||||
database_result[0].albums.push(Album {
|
||||
id: album_id.clone(),
|
||||
date: AlbumDate::default(),
|
||||
seq: AlbumSeq::default(),
|
||||
tracks: vec![],
|
||||
});
|
||||
|
||||
database
|
||||
.expect_load()
|
||||
.times(1)
|
||||
.return_once(|| Ok(database_result));
|
||||
database.expect_save().times(2).returning(|_| Ok(()));
|
||||
|
||||
let mut music_hoard = MusicHoard::database(database).unwrap();
|
||||
assert_eq!(music_hoard.collection[0].albums[0].seq, AlbumSeq(0));
|
||||
|
||||
// Seting seq on an album not belonging to the artist is an error.
|
||||
assert!(music_hoard
|
||||
.set_album_seq(&artist_id, &album_id_2, 6)
|
||||
.is_err());
|
||||
assert_eq!(music_hoard.collection[0].albums[0].seq, AlbumSeq(0));
|
||||
|
||||
// Set seq.
|
||||
assert!(music_hoard.set_album_seq(&artist_id, &album_id, 6).is_ok());
|
||||
assert_eq!(music_hoard.collection[0].albums[0].seq, AlbumSeq(6));
|
||||
|
||||
// Clearing seq on an album that does not exist is an error.
|
||||
assert!(music_hoard
|
||||
.clear_album_seq(&artist_id, &album_id_2)
|
||||
.is_err());
|
||||
|
||||
// Clear seq.
|
||||
assert!(music_hoard.clear_album_seq(&artist_id, &album_id).is_ok());
|
||||
assert_eq!(music_hoard.collection[0].albums[0].seq, AlbumSeq(0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn merge_collection_no_overlap() {
|
||||
let half: usize = FULL_COLLECTION.len() / 2;
|
||||
|
@ -1,5 +1,5 @@
|
||||
use once_cell::sync::Lazy;
|
||||
use std::collections::HashMap;
|
||||
use std::{collections::HashMap, str::FromStr};
|
||||
|
||||
use crate::core::collection::{
|
||||
album::{Album, AlbumDate, AlbumId, AlbumMonth, AlbumSeq},
|
||||
|
18
src/tests.rs
18
src/tests.rs
@ -454,11 +454,9 @@ macro_rules! full_collection {
|
||||
let artist_a = iter.next().unwrap();
|
||||
assert_eq!(artist_a.id.name, "Album_Artist ‘A’");
|
||||
|
||||
artist_a.musicbrainz = Some(
|
||||
MusicBrainz::new(
|
||||
artist_a.musicbrainz = Some(MusicBrainz::from_str(
|
||||
"https://musicbrainz.org/artist/00000000-0000-0000-0000-000000000000",
|
||||
).unwrap(),
|
||||
);
|
||||
).unwrap());
|
||||
|
||||
artist_a.properties = HashMap::from([
|
||||
(String::from("MusicButler"), vec![
|
||||
@ -477,11 +475,9 @@ macro_rules! full_collection {
|
||||
let artist_b = iter.next().unwrap();
|
||||
assert_eq!(artist_b.id.name, "Album_Artist ‘B’");
|
||||
|
||||
artist_b.musicbrainz = Some(
|
||||
MusicBrainz::new(
|
||||
artist_b.musicbrainz = Some(MusicBrainz::from_str(
|
||||
"https://musicbrainz.org/artist/11111111-1111-1111-1111-111111111111",
|
||||
).unwrap(),
|
||||
);
|
||||
).unwrap());
|
||||
|
||||
artist_b.properties = HashMap::from([
|
||||
(String::from("MusicButler"), vec![
|
||||
@ -504,11 +500,9 @@ macro_rules! full_collection {
|
||||
let artist_c = iter.next().unwrap();
|
||||
assert_eq!(artist_c.id.name, "The Album_Artist ‘C’");
|
||||
|
||||
artist_c.musicbrainz = Some(
|
||||
MusicBrainz::new(
|
||||
artist_c.musicbrainz = Some(MusicBrainz::from_str(
|
||||
"https://musicbrainz.org/artist/11111111-1111-1111-1111-111111111111",
|
||||
).unwrap(),
|
||||
);
|
||||
).unwrap());
|
||||
|
||||
// Nothing for artist_d
|
||||
|
||||
|
@ -1,10 +1,11 @@
|
||||
use std::{collections::HashMap, str::FromStr};
|
||||
|
||||
use musichoard::collection::{
|
||||
album::{Album, AlbumDate, AlbumId, AlbumMonth, AlbumSeq},
|
||||
artist::{Artist, ArtistId, MusicBrainz},
|
||||
track::{Track, TrackFormat, TrackId, TrackNum, TrackQuality},
|
||||
};
|
||||
use once_cell::sync::Lazy;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::tests::*;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
use once_cell::sync::Lazy;
|
||||
use std::collections::HashMap;
|
||||
use std::{collections::HashMap, str::FromStr};
|
||||
|
||||
use musichoard::collection::{
|
||||
album::{Album, AlbumDate, AlbumId, AlbumMonth, AlbumSeq},
|
||||
@ -17,8 +17,8 @@ pub static COLLECTION: Lazy<Vec<Artist>> = Lazy::new(|| -> Collection {
|
||||
sort: Some(ArtistId{
|
||||
name: String::from("Arkona")
|
||||
}),
|
||||
musicbrainz: Some(MusicBrainz::new(
|
||||
"https://musicbrainz.org/artist/baad262d-55ef-427a-83c7-f7530964f212",
|
||||
musicbrainz: Some(MusicBrainz::from_str(
|
||||
"https://musicbrainz.org/artist/baad262d-55ef-427a-83c7-f7530964f212"
|
||||
).unwrap()),
|
||||
properties: HashMap::from([
|
||||
(String::from("MusicButler"), vec![
|
||||
@ -204,7 +204,7 @@ pub static COLLECTION: Lazy<Vec<Artist>> = Lazy::new(|| -> Collection {
|
||||
name: String::from("Eluveitie"),
|
||||
},
|
||||
sort: None,
|
||||
musicbrainz: Some(MusicBrainz::new(
|
||||
musicbrainz: Some(MusicBrainz::from_str(
|
||||
"https://musicbrainz.org/artist/8000598a-5edb-401c-8e6d-36b167feaf38",
|
||||
).unwrap()),
|
||||
properties: HashMap::from([
|
||||
@ -447,7 +447,7 @@ pub static COLLECTION: Lazy<Vec<Artist>> = Lazy::new(|| -> Collection {
|
||||
name: String::from("Frontside"),
|
||||
},
|
||||
sort: None,
|
||||
musicbrainz: Some(MusicBrainz::new(
|
||||
musicbrainz: Some(MusicBrainz::from_str(
|
||||
"https://musicbrainz.org/artist/3a901353-fccd-4afd-ad01-9c03f451b490",
|
||||
).unwrap()),
|
||||
properties: HashMap::from([
|
||||
@ -600,7 +600,7 @@ pub static COLLECTION: Lazy<Vec<Artist>> = Lazy::new(|| -> Collection {
|
||||
sort: Some(ArtistId {
|
||||
name: String::from("Heaven’s Basement"),
|
||||
}),
|
||||
musicbrainz: Some(MusicBrainz::new(
|
||||
musicbrainz: Some(MusicBrainz::from_str(
|
||||
"https://musicbrainz.org/artist/c2c4d56a-d599-4a18-bd2f-ae644e2198cc",
|
||||
).unwrap()),
|
||||
properties: HashMap::from([
|
||||
@ -730,7 +730,7 @@ pub static COLLECTION: Lazy<Vec<Artist>> = Lazy::new(|| -> Collection {
|
||||
name: String::from("Metallica"),
|
||||
},
|
||||
sort: None,
|
||||
musicbrainz: Some(MusicBrainz::new(
|
||||
musicbrainz: Some(MusicBrainz::from_str(
|
||||
"https://musicbrainz.org/artist/65f4f0c5-ef9e-490c-aee3-909e7ae6b2ab",
|
||||
).unwrap()),
|
||||
properties: HashMap::from([
|
||||
|
Loading…
Reference in New Issue
Block a user