diff --git a/src/lib.rs b/src/lib.rs index 8ddec99..a6862eb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -48,7 +48,7 @@ impl fmt::Display for InvalidUrlError { } /// MusicBrainz reference. -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord)] pub struct MusicBrainz(Url); impl MusicBrainz { @@ -93,7 +93,7 @@ impl IMbid for MusicBrainz { } /// MusicButler reference. -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord)] pub struct MusicButler(Url); impl MusicButler { @@ -126,7 +126,7 @@ impl IUrl for MusicButler { } /// Bandcamp reference. -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord)] pub struct Bandcamp(Url); impl Bandcamp { @@ -159,7 +159,7 @@ impl IUrl for Bandcamp { } /// Qobuz reference. -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord)] pub struct Qobuz(Url); impl Qobuz { @@ -192,7 +192,7 @@ impl IUrl for Qobuz { } /// The track file format. -#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq, Hash)] pub enum Format { Flac, Mp3, @@ -288,6 +288,17 @@ pub struct ArtistProperties { pub qobuz: Option, } +impl Merge for ArtistProperties { + fn merge(mut self, other: Self) -> Self { + self.musicbrainz = Self::merge_opts(self.musicbrainz, other.musicbrainz); + self.musicbutler = Self::merge_vecs(self.musicbutler, other.musicbutler); + self.bandcamp = Self::merge_vecs(self.bandcamp, other.bandcamp); + self.qobuz = Self::merge_opts(self.qobuz, other.qobuz); + + self + } +} + /// An artist. #[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)] pub struct Artist { @@ -311,6 +322,7 @@ impl Ord for Artist { impl Merge for Artist { fn merge(mut self, other: Self) -> Self { assert_eq!(self.id, other.id); + self.properties = self.properties.merge(other.properties); self.albums = MergeSorted::new(self.albums.into_iter(), other.albums.into_iter()).collect(); self } @@ -321,6 +333,22 @@ pub type Collection = Vec; trait Merge { fn merge(self, other: Self) -> Self; + + fn merge_opts(this: Option, other: Option) -> Option { + match (this, other) { + (Some(t), Some(_)) => Some(t), + (Some(t), None) => Some(t), + (None, Some(o)) => Some(o), + (None, None) => None, + } + } + + fn merge_vecs(mut this: Vec, mut other: Vec) -> Vec { + this.append(&mut other); + this.sort_unstable(); + this.dedup(); + this + } } struct MergeSorted @@ -740,6 +768,7 @@ mod tests { right.id = left.id.clone(); let mut expected = left.clone(); + expected.properties = expected.properties.merge(right.clone().properties); expected.albums.append(&mut right.albums.clone()); expected.albums.sort_unstable(); @@ -756,6 +785,7 @@ mod tests { left.albums.sort_unstable(); let mut expected = left.clone(); + expected.properties = expected.properties.merge(right.clone().properties); expected.albums.append(&mut right.albums.clone()); expected.albums.sort_unstable(); expected.albums.dedup(); diff --git a/src/library/mod.rs b/src/library/mod.rs index 98905c7..61c34da 100644 --- a/src/library/mod.rs +++ b/src/library/mod.rs @@ -18,7 +18,7 @@ pub trait ILibrary { } /// An item from the library. An item corresponds to an individual file (usually a single track). -#[derive(Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq, Eq, Hash)] pub struct Item { pub album_artist: String, pub album_year: u32, diff --git a/tests/database/json.rs b/tests/database/json.rs index 2761ecb..6a1f698 100644 --- a/tests/database/json.rs +++ b/tests/database/json.rs @@ -10,9 +10,9 @@ use musichoard::{ use once_cell::sync::Lazy; use tempfile::NamedTempFile; -use crate::COLLECTION; +use crate::testlib::COLLECTION; -static DATABASE_TEST_FILE: Lazy = +pub static DATABASE_TEST_FILE: Lazy = Lazy::new(|| fs::canonicalize("./tests/files/database/database.json").unwrap()); #[test] diff --git a/tests/database/mod.rs b/tests/database/mod.rs index 084073c..dfa5715 100644 --- a/tests/database/mod.rs +++ b/tests/database/mod.rs @@ -1,2 +1,2 @@ #[cfg(feature = "database-json")] -mod json; +pub mod json; diff --git a/tests/files/database/database.json b/tests/files/database/database.json index de471d8..fa5540e 100644 --- a/tests/files/database/database.json +++ b/tests/files/database/database.json @@ -1 +1 @@ -[{"id":{"name":"Аркона"},"properties":{"musicbrainz":"https://musicbrainz.org/artist/baad262d-55ef-427a-83c7-f7530964f212","musicbutler":["https://www.musicbutler.io/artist-page/283448581"],"bandcamp":["https://arkonamoscow.bandcamp.com/"],"qobuz":"https://www.qobuz.com/nl-nl/interpreter/arkona/download-streaming-albums"},"albums":[{"id":{"year":2011,"title":"Slovo"},"tracks":[{"id":{"number":1,"title":"Az’"},"artist":["Аркона"],"quality":{"format":"Flac","bitrate":992}},{"id":{"number":2,"title":"Arkaim"},"artist":["Аркона"],"quality":{"format":"Flac","bitrate":1061}},{"id":{"number":3,"title":"Bol’no mne"},"artist":["Аркона"],"quality":{"format":"Flac","bitrate":1004}},{"id":{"number":4,"title":"Leshiy"},"artist":["Аркона"],"quality":{"format":"Flac","bitrate":1077}},{"id":{"number":5,"title":"Zakliatie"},"artist":["Аркона"],"quality":{"format":"Flac","bitrate":1041}},{"id":{"number":6,"title":"Predok"},"artist":["Аркона"],"quality":{"format":"Flac","bitrate":756}},{"id":{"number":7,"title":"Nikogda"},"artist":["Аркона"],"quality":{"format":"Flac","bitrate":1059}},{"id":{"number":8,"title":"Tam za tumanami"},"artist":["Аркона"],"quality":{"format":"Flac","bitrate":1023}},{"id":{"number":9,"title":"Potomok"},"artist":["Аркона"],"quality":{"format":"Flac","bitrate":838}},{"id":{"number":10,"title":"Slovo"},"artist":["Аркона"],"quality":{"format":"Flac","bitrate":1028}},{"id":{"number":11,"title":"Odna"},"artist":["Аркона"],"quality":{"format":"Flac","bitrate":991}},{"id":{"number":12,"title":"Vo moiom sadochke…"},"artist":["Аркона"],"quality":{"format":"Flac","bitrate":919}},{"id":{"number":13,"title":"Stenka na stenku"},"artist":["Аркона"],"quality":{"format":"Flac","bitrate":1039}},{"id":{"number":14,"title":"Zimushka"},"artist":["Аркона"],"quality":{"format":"Flac","bitrate":974}}]}]},{"id":{"name":"Eluveitie"},"properties":{"musicbrainz":"https://musicbrainz.org/artist/8000598a-5edb-401c-8e6d-36b167feaf38","musicbutler":["https://www.musicbutler.io/artist-page/269358403"],"bandcamp":[],"qobuz":"https://www.qobuz.com/nl-nl/interpreter/eluveitie/download-streaming-albums"},"albums":[{"id":{"year":2008,"title":"Slania"},"tracks":[{"id":{"number":1,"title":"Samon"},"artist":["Eluveitie"],"quality":{"format":"Flac","bitrate":953}},{"id":{"number":2,"title":"Primordial Breath"},"artist":["Eluveitie"],"quality":{"format":"Flac","bitrate":1103}},{"id":{"number":3,"title":"Inis Mona"},"artist":["Eluveitie"],"quality":{"format":"Flac","bitrate":1117}},{"id":{"number":4,"title":"Gray Sublime Archon"},"artist":["Eluveitie"],"quality":{"format":"Flac","bitrate":1092}},{"id":{"number":5,"title":"Anagantios"},"artist":["Eluveitie"],"quality":{"format":"Flac","bitrate":923}},{"id":{"number":6,"title":"Bloodstained Ground"},"artist":["Eluveitie"],"quality":{"format":"Flac","bitrate":1098}},{"id":{"number":7,"title":"The Somber Lay"},"artist":["Eluveitie"],"quality":{"format":"Flac","bitrate":1068}},{"id":{"number":8,"title":"Slanias Song"},"artist":["Eluveitie"],"quality":{"format":"Flac","bitrate":1098}},{"id":{"number":9,"title":"Giamonios"},"artist":["Eluveitie"],"quality":{"format":"Flac","bitrate":825}},{"id":{"number":10,"title":"Tarvos"},"artist":["Eluveitie"],"quality":{"format":"Flac","bitrate":1115}},{"id":{"number":11,"title":"Calling the Rain"},"artist":["Eluveitie"],"quality":{"format":"Flac","bitrate":1096}},{"id":{"number":12,"title":"Elembivos"},"artist":["Eluveitie"],"quality":{"format":"Flac","bitrate":1059}}]},{"id":{"year":2004,"title":"Vên [re‐recorded]"},"tracks":[{"id":{"number":1,"title":"Verja Urit an Bitus"},"artist":["Eluveitie"],"quality":{"format":"Flac","bitrate":961}},{"id":{"number":2,"title":"Uis Elveti"},"artist":["Eluveitie"],"quality":{"format":"Flac","bitrate":1067}},{"id":{"number":3,"title":"Ôrô"},"artist":["Eluveitie"],"quality":{"format":"Flac","bitrate":933}},{"id":{"number":4,"title":"Lament"},"artist":["Eluveitie"],"quality":{"format":"Flac","bitrate":1083}},{"id":{"number":5,"title":"Druid"},"artist":["Eluveitie"],"quality":{"format":"Flac","bitrate":1073}},{"id":{"number":6,"title":"Jêzaïg"},"artist":["Eluveitie"],"quality":{"format":"Flac","bitrate":1002}}]}]},{"id":{"name":"Frontside"},"properties":{"musicbrainz":"https://musicbrainz.org/artist/3a901353-fccd-4afd-ad01-9c03f451b490","musicbutler":["https://www.musicbutler.io/artist-page/826588800"],"bandcamp":[],"qobuz":"https://www.qobuz.com/nl-nl/interpreter/frontside/download-streaming-albums"},"albums":[{"id":{"year":2001,"title":"…nasze jest królestwo, potęga i chwała na wieki…"},"tracks":[{"id":{"number":1,"title":"Intro = Chaos"},"artist":["Frontside"],"quality":{"format":"Flac","bitrate":1024}},{"id":{"number":2,"title":"Modlitwa"},"artist":["Frontside"],"quality":{"format":"Flac","bitrate":1073}},{"id":{"number":3,"title":"Długa droga z piekła"},"artist":["Frontside"],"quality":{"format":"Flac","bitrate":1058}},{"id":{"number":4,"title":"Synowie ognia"},"artist":["Frontside"],"quality":{"format":"Flac","bitrate":1066}},{"id":{"number":5,"title":"1902"},"artist":["Frontside"],"quality":{"format":"Flac","bitrate":1074}},{"id":{"number":6,"title":"Krew za krew"},"artist":["Frontside"],"quality":{"format":"Flac","bitrate":1080}},{"id":{"number":7,"title":"Kulminacja"},"artist":["Frontside"],"quality":{"format":"Flac","bitrate":992}},{"id":{"number":8,"title":"Judasz"},"artist":["Frontside"],"quality":{"format":"Flac","bitrate":1018}},{"id":{"number":9,"title":"Więzy"},"artist":["Frontside"],"quality":{"format":"Flac","bitrate":1077}},{"id":{"number":10,"title":"Zagubione dusze"},"artist":["Frontside"],"quality":{"format":"Flac","bitrate":1033}},{"id":{"number":11,"title":"Linia życia"},"artist":["Frontside"],"quality":{"format":"Flac","bitrate":987}}]}]},{"id":{"name":"Heaven’s Basement"},"properties":{"musicbrainz":"https://musicbrainz.org/artist/c2c4d56a-d599-4a18-bd2f-ae644e2198cc","musicbutler":["https://www.musicbutler.io/artist-page/291158685"],"bandcamp":[],"qobuz":"https://www.qobuz.com/nl-nl/interpreter/heaven-s-basement/download-streaming-albums"},"albums":[{"id":{"year":2011,"title":"Unbreakable"},"tracks":[{"id":{"number":1,"title":"Unbreakable"},"artist":["Heaven’s Basement"],"quality":{"format":"Mp3","bitrate":208}},{"id":{"number":2,"title":"Guilt Trips and Sins"},"artist":["Heaven’s Basement"],"quality":{"format":"Mp3","bitrate":205}},{"id":{"number":3,"title":"The Long Goodbye"},"artist":["Heaven’s Basement"],"quality":{"format":"Mp3","bitrate":227}},{"id":{"number":4,"title":"Close Encounters"},"artist":["Heaven’s Basement"],"quality":{"format":"Mp3","bitrate":213}},{"id":{"number":5,"title":"Paranoia"},"artist":["Heaven’s Basement"],"quality":{"format":"Mp3","bitrate":218}},{"id":{"number":6,"title":"Let Me Out of Here"},"artist":["Heaven’s Basement"],"quality":{"format":"Mp3","bitrate":207}},{"id":{"number":7,"title":"Leeches"},"artist":["Heaven’s Basement"],"quality":{"format":"Mp3","bitrate":225}}]}]},{"id":{"name":"Metallica"},"properties":{"musicbrainz":"https://musicbrainz.org/artist/65f4f0c5-ef9e-490c-aee3-909e7ae6b2ab","musicbutler":["https://www.musicbutler.io/artist-page/3996865"],"bandcamp":[],"qobuz":"https://www.qobuz.com/nl-nl/interpreter/metallica/download-streaming-albums"},"albums":[{"id":{"year":1984,"title":"Ride the Lightning"},"tracks":[{"id":{"number":1,"title":"Fight Fire with Fire"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":954}},{"id":{"number":2,"title":"Ride the Lightning"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":951}},{"id":{"number":3,"title":"For Whom the Bell Tolls"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":889}},{"id":{"number":4,"title":"Fade to Black"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":939}},{"id":{"number":5,"title":"Trapped under Ice"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":955}},{"id":{"number":6,"title":"Escape"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":941}},{"id":{"number":7,"title":"Creeping Death"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":958}},{"id":{"number":8,"title":"The Call of Ktulu"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":888}}]},{"id":{"year":1999,"title":"S&M"},"tracks":[{"id":{"number":1,"title":"The Ecstasy of Gold"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":875}},{"id":{"number":2,"title":"The Call of Ktulu"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":1030}},{"id":{"number":3,"title":"Master of Puppets"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":1082}},{"id":{"number":4,"title":"Of Wolf and Man"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":1115}},{"id":{"number":5,"title":"The Thing That Should Not Be"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":1029}},{"id":{"number":6,"title":"Fuel"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":1057}},{"id":{"number":7,"title":"The Memory Remains"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":1080}},{"id":{"number":8,"title":"No Leaf Clover"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":1004}},{"id":{"number":9,"title":"Hero of the Day"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":962}},{"id":{"number":10,"title":"Devil’s Dance"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":1076}},{"id":{"number":11,"title":"Bleeding Me"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":993}},{"id":{"number":12,"title":"Nothing Else Matters"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":875}},{"id":{"number":13,"title":"Until It Sleeps"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":1038}},{"id":{"number":14,"title":"For Whom the Bell Tolls"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":1072}},{"id":{"number":15,"title":"−Human"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":1029}},{"id":{"number":16,"title":"Wherever I May Roam"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":1035}},{"id":{"number":17,"title":"Outlaw Torn"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":1042}},{"id":{"number":18,"title":"Sad but True"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":1082}},{"id":{"number":19,"title":"One"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":1017}},{"id":{"number":20,"title":"Enter Sandman"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":993}},{"id":{"number":21,"title":"Battery"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":967}}]}]}] \ No newline at end of file +[{"id":{"name":"Eluveitie"},"properties":{"musicbrainz":"https://musicbrainz.org/artist/8000598a-5edb-401c-8e6d-36b167feaf38","musicbutler":["https://www.musicbutler.io/artist-page/269358403"],"bandcamp":[],"qobuz":"https://www.qobuz.com/nl-nl/interpreter/eluveitie/download-streaming-albums"},"albums":[{"id":{"year":2004,"title":"Vên [re‐recorded]"},"tracks":[{"id":{"number":1,"title":"Verja Urit an Bitus"},"artist":["Eluveitie"],"quality":{"format":"Flac","bitrate":961}},{"id":{"number":2,"title":"Uis Elveti"},"artist":["Eluveitie"],"quality":{"format":"Flac","bitrate":1067}},{"id":{"number":3,"title":"Ôrô"},"artist":["Eluveitie"],"quality":{"format":"Flac","bitrate":933}},{"id":{"number":4,"title":"Lament"},"artist":["Eluveitie"],"quality":{"format":"Flac","bitrate":1083}},{"id":{"number":5,"title":"Druid"},"artist":["Eluveitie"],"quality":{"format":"Flac","bitrate":1073}},{"id":{"number":6,"title":"Jêzaïg"},"artist":["Eluveitie"],"quality":{"format":"Flac","bitrate":1002}}]},{"id":{"year":2008,"title":"Slania"},"tracks":[{"id":{"number":1,"title":"Samon"},"artist":["Eluveitie"],"quality":{"format":"Flac","bitrate":953}},{"id":{"number":2,"title":"Primordial Breath"},"artist":["Eluveitie"],"quality":{"format":"Flac","bitrate":1103}},{"id":{"number":3,"title":"Inis Mona"},"artist":["Eluveitie"],"quality":{"format":"Flac","bitrate":1117}},{"id":{"number":4,"title":"Gray Sublime Archon"},"artist":["Eluveitie"],"quality":{"format":"Flac","bitrate":1092}},{"id":{"number":5,"title":"Anagantios"},"artist":["Eluveitie"],"quality":{"format":"Flac","bitrate":923}},{"id":{"number":6,"title":"Bloodstained Ground"},"artist":["Eluveitie"],"quality":{"format":"Flac","bitrate":1098}},{"id":{"number":7,"title":"The Somber Lay"},"artist":["Eluveitie"],"quality":{"format":"Flac","bitrate":1068}},{"id":{"number":8,"title":"Slanias Song"},"artist":["Eluveitie"],"quality":{"format":"Flac","bitrate":1098}},{"id":{"number":9,"title":"Giamonios"},"artist":["Eluveitie"],"quality":{"format":"Flac","bitrate":825}},{"id":{"number":10,"title":"Tarvos"},"artist":["Eluveitie"],"quality":{"format":"Flac","bitrate":1115}},{"id":{"number":11,"title":"Calling the Rain"},"artist":["Eluveitie"],"quality":{"format":"Flac","bitrate":1096}},{"id":{"number":12,"title":"Elembivos"},"artist":["Eluveitie"],"quality":{"format":"Flac","bitrate":1059}}]}]},{"id":{"name":"Frontside"},"properties":{"musicbrainz":"https://musicbrainz.org/artist/3a901353-fccd-4afd-ad01-9c03f451b490","musicbutler":["https://www.musicbutler.io/artist-page/826588800"],"bandcamp":[],"qobuz":"https://www.qobuz.com/nl-nl/interpreter/frontside/download-streaming-albums"},"albums":[{"id":{"year":2001,"title":"…nasze jest królestwo, potęga i chwała na wieki…"},"tracks":[{"id":{"number":1,"title":"Intro = Chaos"},"artist":["Frontside"],"quality":{"format":"Flac","bitrate":1024}},{"id":{"number":2,"title":"Modlitwa"},"artist":["Frontside"],"quality":{"format":"Flac","bitrate":1073}},{"id":{"number":3,"title":"Długa droga z piekła"},"artist":["Frontside"],"quality":{"format":"Flac","bitrate":1058}},{"id":{"number":4,"title":"Synowie ognia"},"artist":["Frontside"],"quality":{"format":"Flac","bitrate":1066}},{"id":{"number":5,"title":"1902"},"artist":["Frontside"],"quality":{"format":"Flac","bitrate":1074}},{"id":{"number":6,"title":"Krew za krew"},"artist":["Frontside"],"quality":{"format":"Flac","bitrate":1080}},{"id":{"number":7,"title":"Kulminacja"},"artist":["Frontside"],"quality":{"format":"Flac","bitrate":992}},{"id":{"number":8,"title":"Judasz"},"artist":["Frontside"],"quality":{"format":"Flac","bitrate":1018}},{"id":{"number":9,"title":"Więzy"},"artist":["Frontside"],"quality":{"format":"Flac","bitrate":1077}},{"id":{"number":10,"title":"Zagubione dusze"},"artist":["Frontside"],"quality":{"format":"Flac","bitrate":1033}},{"id":{"number":11,"title":"Linia życia"},"artist":["Frontside"],"quality":{"format":"Flac","bitrate":987}}]}]},{"id":{"name":"Heaven’s Basement"},"properties":{"musicbrainz":"https://musicbrainz.org/artist/c2c4d56a-d599-4a18-bd2f-ae644e2198cc","musicbutler":["https://www.musicbutler.io/artist-page/291158685"],"bandcamp":[],"qobuz":"https://www.qobuz.com/nl-nl/interpreter/heaven-s-basement/download-streaming-albums"},"albums":[{"id":{"year":2011,"title":"Unbreakable"},"tracks":[{"id":{"number":1,"title":"Unbreakable"},"artist":["Heaven’s Basement"],"quality":{"format":"Mp3","bitrate":208}},{"id":{"number":2,"title":"Guilt Trips and Sins"},"artist":["Heaven’s Basement"],"quality":{"format":"Mp3","bitrate":205}},{"id":{"number":3,"title":"The Long Goodbye"},"artist":["Heaven’s Basement"],"quality":{"format":"Mp3","bitrate":227}},{"id":{"number":4,"title":"Close Encounters"},"artist":["Heaven’s Basement"],"quality":{"format":"Mp3","bitrate":213}},{"id":{"number":5,"title":"Paranoia"},"artist":["Heaven’s Basement"],"quality":{"format":"Mp3","bitrate":218}},{"id":{"number":6,"title":"Let Me Out of Here"},"artist":["Heaven’s Basement"],"quality":{"format":"Mp3","bitrate":207}},{"id":{"number":7,"title":"Leeches"},"artist":["Heaven’s Basement"],"quality":{"format":"Mp3","bitrate":225}}]}]},{"id":{"name":"Metallica"},"properties":{"musicbrainz":"https://musicbrainz.org/artist/65f4f0c5-ef9e-490c-aee3-909e7ae6b2ab","musicbutler":["https://www.musicbutler.io/artist-page/3996865"],"bandcamp":[],"qobuz":"https://www.qobuz.com/nl-nl/interpreter/metallica/download-streaming-albums"},"albums":[{"id":{"year":1984,"title":"Ride the Lightning"},"tracks":[{"id":{"number":1,"title":"Fight Fire with Fire"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":954}},{"id":{"number":2,"title":"Ride the Lightning"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":951}},{"id":{"number":3,"title":"For Whom the Bell Tolls"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":889}},{"id":{"number":4,"title":"Fade to Black"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":939}},{"id":{"number":5,"title":"Trapped under Ice"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":955}},{"id":{"number":6,"title":"Escape"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":941}},{"id":{"number":7,"title":"Creeping Death"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":958}},{"id":{"number":8,"title":"The Call of Ktulu"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":888}}]},{"id":{"year":1999,"title":"S&M"},"tracks":[{"id":{"number":1,"title":"The Ecstasy of Gold"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":875}},{"id":{"number":2,"title":"The Call of Ktulu"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":1030}},{"id":{"number":3,"title":"Master of Puppets"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":1082}},{"id":{"number":4,"title":"Of Wolf and Man"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":1115}},{"id":{"number":5,"title":"The Thing That Should Not Be"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":1029}},{"id":{"number":6,"title":"Fuel"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":1057}},{"id":{"number":7,"title":"The Memory Remains"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":1080}},{"id":{"number":8,"title":"No Leaf Clover"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":1004}},{"id":{"number":9,"title":"Hero of the Day"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":962}},{"id":{"number":10,"title":"Devil’s Dance"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":1076}},{"id":{"number":11,"title":"Bleeding Me"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":993}},{"id":{"number":12,"title":"Nothing Else Matters"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":875}},{"id":{"number":13,"title":"Until It Sleeps"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":1038}},{"id":{"number":14,"title":"For Whom the Bell Tolls"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":1072}},{"id":{"number":15,"title":"−Human"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":1029}},{"id":{"number":16,"title":"Wherever I May Roam"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":1035}},{"id":{"number":17,"title":"Outlaw Torn"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":1042}},{"id":{"number":18,"title":"Sad but True"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":1082}},{"id":{"number":19,"title":"One"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":1017}},{"id":{"number":20,"title":"Enter Sandman"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":993}},{"id":{"number":21,"title":"Battery"},"artist":["Metallica"],"quality":{"format":"Flac","bitrate":967}}]}]},{"id":{"name":"Аркона"},"properties":{"musicbrainz":"https://musicbrainz.org/artist/baad262d-55ef-427a-83c7-f7530964f212","musicbutler":["https://www.musicbutler.io/artist-page/283448581"],"bandcamp":["https://arkonamoscow.bandcamp.com/"],"qobuz":"https://www.qobuz.com/nl-nl/interpreter/arkona/download-streaming-albums"},"albums":[{"id":{"year":2011,"title":"Slovo"},"tracks":[{"id":{"number":1,"title":"Az’"},"artist":["Аркона"],"quality":{"format":"Flac","bitrate":992}},{"id":{"number":2,"title":"Arkaim"},"artist":["Аркона"],"quality":{"format":"Flac","bitrate":1061}},{"id":{"number":3,"title":"Bol’no mne"},"artist":["Аркона"],"quality":{"format":"Flac","bitrate":1004}},{"id":{"number":4,"title":"Leshiy"},"artist":["Аркона"],"quality":{"format":"Flac","bitrate":1077}},{"id":{"number":5,"title":"Zakliatie"},"artist":["Аркона"],"quality":{"format":"Flac","bitrate":1041}},{"id":{"number":6,"title":"Predok"},"artist":["Аркона"],"quality":{"format":"Flac","bitrate":756}},{"id":{"number":7,"title":"Nikogda"},"artist":["Аркона"],"quality":{"format":"Flac","bitrate":1059}},{"id":{"number":8,"title":"Tam za tumanami"},"artist":["Аркона"],"quality":{"format":"Flac","bitrate":1023}},{"id":{"number":9,"title":"Potomok"},"artist":["Аркона"],"quality":{"format":"Flac","bitrate":838}},{"id":{"number":10,"title":"Slovo"},"artist":["Аркона"],"quality":{"format":"Flac","bitrate":1028}},{"id":{"number":11,"title":"Odna"},"artist":["Аркона"],"quality":{"format":"Flac","bitrate":991}},{"id":{"number":12,"title":"Vo moiom sadochke…"},"artist":["Аркона"],"quality":{"format":"Flac","bitrate":919}},{"id":{"number":13,"title":"Stenka na stenku"},"artist":["Аркона"],"quality":{"format":"Flac","bitrate":1039}},{"id":{"number":14,"title":"Zimushka"},"artist":["Аркона"],"quality":{"format":"Flac","bitrate":974}}]}]}] \ No newline at end of file diff --git a/tests/lib.rs b/tests/lib.rs index 2e44778..c1e74bd 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -1,1029 +1,64 @@ mod database; mod library; -use musichoard::{ - Album, AlbumId, Artist, ArtistId, ArtistProperties, Bandcamp, Collection, Format, MusicBrainz, - MusicButler, Qobuz, Quality, Track, TrackId, -}; -use once_cell::sync::Lazy; +mod testlib; -static COLLECTION: Lazy> = Lazy::new(|| -> Collection { - vec![ - Artist { - id: ArtistId { - name: String::from("Аркона"), - }, - properties: ArtistProperties { - musicbrainz: Some(MusicBrainz::new( - "https://musicbrainz.org/artist/baad262d-55ef-427a-83c7-f7530964f212", - ).unwrap()), - musicbutler: vec![ - MusicButler::new("https://www.musicbutler.io/artist-page/283448581").unwrap(), - ], - bandcamp: vec![ - Bandcamp::new("https://arkonamoscow.bandcamp.com/").unwrap(), - ], - qobuz: Some(Qobuz::new( - "https://www.qobuz.com/nl-nl/interpreter/arkona/download-streaming-albums", - ).unwrap()), - }, - albums: vec![Album { - id: AlbumId { - year: 2011, - title: String::from("Slovo"), - }, - tracks: vec![ - Track { - id: TrackId { - number: 01, - title: String::from("Az’"), - }, - artist: vec![String::from("Аркона")], - quality: Quality { - format: Format::Flac, - bitrate: 992, - }, - }, - Track { - id: TrackId { - number: 02, - title: String::from("Arkaim"), - }, - artist: vec![String::from("Аркона")], - quality: Quality { - format: Format::Flac, - bitrate: 1061, - }, - }, - Track { - id: TrackId { - number: 03, - title: String::from("Bol’no mne"), - }, - artist: vec![String::from("Аркона")], - quality: Quality { - format: Format::Flac, - bitrate: 1004, - }, - }, - Track { - id: TrackId { - number: 04, - title: String::from("Leshiy"), - }, - artist: vec![String::from("Аркона")], - quality: Quality { - format: Format::Flac, - bitrate: 1077, - }, - }, - Track { - id: TrackId { - number: 05, - title: String::from("Zakliatie"), - }, - artist: vec![String::from("Аркона")], - quality: Quality { - format: Format::Flac, - bitrate: 1041, - }, - }, - Track { - id: TrackId { - number: 06, - title: String::from("Predok"), - }, - artist: vec![String::from("Аркона")], - quality: Quality { - format: Format::Flac, - bitrate: 756, - }, - }, - Track { - id: TrackId { - number: 07, - title: String::from("Nikogda"), - }, - artist: vec![String::from("Аркона")], - quality: Quality { - format: Format::Flac, - bitrate: 1059, - }, - }, - Track { - id: TrackId { - number: 08, - title: String::from("Tam za tumanami"), - }, - artist: vec![String::from("Аркона")], - quality: Quality { - format: Format::Flac, - bitrate: 1023, - }, - }, - Track { - id: TrackId { - number: 09, - title: String::from("Potomok"), - }, - artist: vec![String::from("Аркона")], - quality: Quality { - format: Format::Flac, - bitrate: 838, - }, - }, - Track { - id: TrackId { - number: 10, - title: String::from("Slovo"), - }, - artist: vec![String::from("Аркона")], - quality: Quality { - format: Format::Flac, - bitrate: 1028, - }, - }, - Track { - id: TrackId { - number: 11, - title: String::from("Odna"), - }, - artist: vec![String::from("Аркона")], - quality: Quality { - format: Format::Flac, - bitrate: 991, - }, - }, - Track { - id: TrackId { - number: 12, - title: String::from("Vo moiom sadochke…"), - }, - artist: vec![String::from("Аркона")], - quality: Quality { - format: Format::Flac, - bitrate: 919, - }, - }, - Track { - id: TrackId { - number: 13, - title: String::from("Stenka na stenku"), - }, - artist: vec![String::from("Аркона")], - quality: Quality { - format: Format::Flac, - bitrate: 1039, - }, - }, - Track { - id: TrackId { - number: 14, - title: String::from("Zimushka"), - }, - artist: vec![String::from("Аркона")], - quality: Quality { - format: Format::Flac, - bitrate: 974, - }, - }, - ], - }], - }, - Artist { - id: ArtistId { - name: String::from("Eluveitie"), - }, - properties: ArtistProperties { - musicbrainz: Some(MusicBrainz::new( - "https://musicbrainz.org/artist/8000598a-5edb-401c-8e6d-36b167feaf38", - ).unwrap()), - musicbutler: vec![ - MusicButler::new("https://www.musicbutler.io/artist-page/269358403").unwrap(), - ], - bandcamp: vec![], - qobuz: Some(Qobuz::new( - "https://www.qobuz.com/nl-nl/interpreter/eluveitie/download-streaming-albums", - ).unwrap()), - }, - albums: vec![ - Album { - id: AlbumId { - year: 2008, - title: String::from("Slania"), - }, - tracks: vec![ - Track { - id: TrackId { - number: 01, - title: String::from("Samon"), - }, - artist: vec![String::from("Eluveitie")], - quality: Quality { - format: Format::Flac, - bitrate: 953, - }, - }, - Track { - id: TrackId { - number: 02, - title: String::from("Primordial Breath"), - }, - artist: vec![String::from("Eluveitie")], - quality: Quality { - format: Format::Flac, - bitrate: 1103, - }, - }, - Track { - id: TrackId { - number: 03, - title: String::from("Inis Mona"), - }, - artist: vec![String::from("Eluveitie")], - quality: Quality { - format: Format::Flac, - bitrate: 1117, - }, - }, - Track { - id: TrackId { - number: 04, - title: String::from("Gray Sublime Archon"), - }, - artist: vec![String::from("Eluveitie")], - quality: Quality { - format: Format::Flac, - bitrate: 1092, - }, - }, - Track { - id: TrackId { - number: 05, - title: String::from("Anagantios"), - }, - artist: vec![String::from("Eluveitie")], - quality: Quality { - format: Format::Flac, - bitrate: 923, - }, - }, - Track { - id: TrackId { - number: 06, - title: String::from("Bloodstained Ground"), - }, - artist: vec![String::from("Eluveitie")], - quality: Quality { - format: Format::Flac, - bitrate: 1098, - }, - }, - Track { - id: TrackId { - number: 07, - title: String::from("The Somber Lay"), - }, - artist: vec![String::from("Eluveitie")], - quality: Quality { - format: Format::Flac, - bitrate: 1068, - }, - }, - Track { - id: TrackId { - number: 08, - title: String::from("Slanias Song"), - }, - artist: vec![String::from("Eluveitie")], - quality: Quality { - format: Format::Flac, - bitrate: 1098, - }, - }, - Track { - id: TrackId { - number: 09, - title: String::from("Giamonios"), - }, - artist: vec![String::from("Eluveitie")], - quality: Quality { - format: Format::Flac, - bitrate: 825, - }, - }, - Track { - id: TrackId { - number: 10, - title: String::from("Tarvos"), - }, - artist: vec![String::from("Eluveitie")], - quality: Quality { - format: Format::Flac, - bitrate: 1115, - }, - }, - Track { - id: TrackId { - number: 11, - title: String::from("Calling the Rain"), - }, - artist: vec![String::from("Eluveitie")], - quality: Quality { - format: Format::Flac, - bitrate: 1096, - }, - }, - Track { - id: TrackId { - number: 12, - title: String::from("Elembivos"), - }, - artist: vec![String::from("Eluveitie")], - quality: Quality { - format: Format::Flac, - bitrate: 1059, - }, - }, - ], - }, - Album { - id: AlbumId { - year: 2004, - title: String::from("Vên [re‐recorded]"), - }, - tracks: vec![ - Track { - id: TrackId { - number: 01, - title: String::from("Verja Urit an Bitus"), - }, - artist: vec![String::from("Eluveitie")], - quality: Quality { - format: Format::Flac, - bitrate: 961, - }, - }, - Track { - id: TrackId { - number: 02, - title: String::from("Uis Elveti"), - }, - artist: vec![String::from("Eluveitie")], - quality: Quality { - format: Format::Flac, - bitrate: 1067, - }, - }, - Track { - id: TrackId { - number: 03, - title: String::from("Ôrô"), - }, - artist: vec![String::from("Eluveitie")], - quality: Quality { - format: Format::Flac, - bitrate: 933, - }, - }, - Track { - id: TrackId { - number: 04, - title: String::from("Lament"), - }, - artist: vec![String::from("Eluveitie")], - quality: Quality { - format: Format::Flac, - bitrate: 1083, - }, - }, - Track { - id: TrackId { - number: 05, - title: String::from("Druid"), - }, - artist: vec![String::from("Eluveitie")], - quality: Quality { - format: Format::Flac, - bitrate: 1073, - }, - }, - Track { - id: TrackId { - number: 06, - title: String::from("Jêzaïg"), - }, - artist: vec![String::from("Eluveitie")], - quality: Quality { - format: Format::Flac, - bitrate: 1002, - }, - }, - ], - }, - ], - }, - Artist { - id: ArtistId { - name: String::from("Frontside"), - }, - properties: ArtistProperties { - musicbrainz: Some(MusicBrainz::new( - "https://musicbrainz.org/artist/3a901353-fccd-4afd-ad01-9c03f451b490", - ).unwrap()), - musicbutler: vec![ - MusicButler::new("https://www.musicbutler.io/artist-page/826588800").unwrap(), - ], - bandcamp: vec![], - qobuz: Some(Qobuz::new( - "https://www.qobuz.com/nl-nl/interpreter/frontside/download-streaming-albums", - ).unwrap()), - }, - albums: vec![Album { - id: AlbumId { - year: 2001, - title: String::from("…nasze jest królestwo, potęga i chwała na wieki…"), - }, - tracks: vec![ - Track { - id: TrackId { - number: 01, - title: String::from("Intro = Chaos"), - }, - artist: vec![String::from("Frontside")], - quality: Quality { - format: Format::Flac, - bitrate: 1024, - }, - }, - Track { - id: TrackId { - number: 02, - title: String::from("Modlitwa"), - }, - artist: vec![String::from("Frontside")], - quality: Quality { - format: Format::Flac, - bitrate: 1073, - }, - }, - Track { - id: TrackId { - number: 03, - title: String::from("Długa droga z piekła"), - }, - artist: vec![String::from("Frontside")], - quality: Quality { - format: Format::Flac, - bitrate: 1058, - }, - }, - Track { - id: TrackId { - number: 04, - title: String::from("Synowie ognia"), - }, - artist: vec![String::from("Frontside")], - quality: Quality { - format: Format::Flac, - bitrate: 1066, - }, - }, - Track { - id: TrackId { - number: 05, - title: String::from("1902"), - }, - artist: vec![String::from("Frontside")], - quality: Quality { - format: Format::Flac, - bitrate: 1074, - }, - }, - Track { - id: TrackId { - number: 06, - title: String::from("Krew za krew"), - }, - artist: vec![String::from("Frontside")], - quality: Quality { - format: Format::Flac, - bitrate: 1080, - }, - }, - Track { - id: TrackId { - number: 07, - title: String::from("Kulminacja"), - }, - artist: vec![String::from("Frontside")], - quality: Quality { - format: Format::Flac, - bitrate: 992, - }, - }, - Track { - id: TrackId { - number: 08, - title: String::from("Judasz"), - }, - artist: vec![String::from("Frontside")], - quality: Quality { - format: Format::Flac, - bitrate: 1018, - }, - }, - Track { - id: TrackId { - number: 09, - title: String::from("Więzy"), - }, - artist: vec![String::from("Frontside")], - quality: Quality { - format: Format::Flac, - bitrate: 1077, - }, - }, - Track { - id: TrackId { - number: 10, - title: String::from("Zagubione dusze"), - }, - artist: vec![String::from("Frontside")], - quality: Quality { - format: Format::Flac, - bitrate: 1033, - }, - }, - Track { - id: TrackId { - number: 11, - title: String::from("Linia życia"), - }, - artist: vec![String::from("Frontside")], - quality: Quality { - format: Format::Flac, - bitrate: 987, - }, - }, - ], - }], - }, - Artist { - id: ArtistId { - name: String::from("Heaven’s Basement"), - }, - properties: ArtistProperties { - musicbrainz: Some(MusicBrainz::new( - "https://musicbrainz.org/artist/c2c4d56a-d599-4a18-bd2f-ae644e2198cc", - ).unwrap()), - musicbutler: vec![ - MusicButler::new("https://www.musicbutler.io/artist-page/291158685").unwrap(), - ], - bandcamp: vec![], - qobuz: Some(Qobuz::new( - "https://www.qobuz.com/nl-nl/interpreter/heaven-s-basement/download-streaming-albums", - ).unwrap()), - }, - albums: vec![Album { - id: AlbumId { - year: 2011, - title: String::from("Unbreakable"), - }, - tracks: vec![ - Track { - id: TrackId { - number: 01, - title: String::from("Unbreakable"), - }, - artist: vec![String::from("Heaven’s Basement")], - quality: Quality { - format: Format::Mp3, - bitrate: 208, - }, - }, - Track { - id: TrackId { - number: 02, - title: String::from("Guilt Trips and Sins"), - }, - artist: vec![String::from("Heaven’s Basement")], - quality: Quality { - format: Format::Mp3, - bitrate: 205, - }, - }, - Track { - id: TrackId { - number: 03, - title: String::from("The Long Goodbye"), - }, - artist: vec![String::from("Heaven’s Basement")], - quality: Quality { - format: Format::Mp3, - bitrate: 227, - }, - }, - Track { - id: TrackId { - number: 04, - title: String::from("Close Encounters"), - }, - artist: vec![String::from("Heaven’s Basement")], - quality: Quality { - format: Format::Mp3, - bitrate: 213, - }, - }, - Track { - id: TrackId { - number: 05, - title: String::from("Paranoia"), - }, - artist: vec![String::from("Heaven’s Basement")], - quality: Quality { - format: Format::Mp3, - bitrate: 218, - }, - }, - Track { - id: TrackId { - number: 06, - title: String::from("Let Me Out of Here"), - }, - artist: vec![String::from("Heaven’s Basement")], - quality: Quality { - format: Format::Mp3, - bitrate: 207, - }, - }, - Track { - id: TrackId { - number: 07, - title: String::from("Leeches"), - }, - artist: vec![String::from("Heaven’s Basement")], - quality: Quality { - format: Format::Mp3, - bitrate: 225, - }, - }, - ], - }], - }, - Artist { - id: ArtistId { - name: String::from("Metallica"), - }, - properties: ArtistProperties { - musicbrainz: Some(MusicBrainz::new( - "https://musicbrainz.org/artist/65f4f0c5-ef9e-490c-aee3-909e7ae6b2ab", - ).unwrap()), - musicbutler: vec![ - MusicButler::new("https://www.musicbutler.io/artist-page/3996865").unwrap(), - ], - bandcamp: vec![], - qobuz: Some(Qobuz::new( - "https://www.qobuz.com/nl-nl/interpreter/metallica/download-streaming-albums", - ).unwrap()), - }, - albums: vec![ - Album { - id: AlbumId { - year: 1984, - title: String::from("Ride the Lightning"), - }, - tracks: vec![ - Track { - id: TrackId { - number: 01, - title: String::from("Fight Fire with Fire"), - }, - artist: vec![String::from("Metallica")], - quality: Quality { - format: Format::Flac, - bitrate: 954, - }, - }, - Track { - id: TrackId { - number: 02, - title: String::from("Ride the Lightning"), - }, - artist: vec![String::from("Metallica")], - quality: Quality { - format: Format::Flac, - bitrate: 951, - }, - }, - Track { - id: TrackId { - number: 03, - title: String::from("For Whom the Bell Tolls"), - }, - artist: vec![String::from("Metallica")], - quality: Quality { - format: Format::Flac, - bitrate: 889, - }, - }, - Track { - id: TrackId { - number: 04, - title: String::from("Fade to Black"), - }, - artist: vec![String::from("Metallica")], - quality: Quality { - format: Format::Flac, - bitrate: 939, - }, - }, - Track { - id: TrackId { - number: 05, - title: String::from("Trapped under Ice"), - }, - artist: vec![String::from("Metallica")], - quality: Quality { - format: Format::Flac, - bitrate: 955, - }, - }, - Track { - id: TrackId { - number: 06, - title: String::from("Escape"), - }, - artist: vec![String::from("Metallica")], - quality: Quality { - format: Format::Flac, - bitrate: 941, - }, - }, - Track { - id: TrackId { - number: 07, - title: String::from("Creeping Death"), - }, - artist: vec![String::from("Metallica")], - quality: Quality { - format: Format::Flac, - bitrate: 958, - }, - }, - Track { - id: TrackId { - number: 08, - title: String::from("The Call of Ktulu"), - }, - artist: vec![String::from("Metallica")], - quality: Quality { - format: Format::Flac, - bitrate: 888, - }, - }, - ], - }, - Album { - id: AlbumId { - year: 1999, - title: String::from("S&M"), - }, - tracks: vec![ - Track { - id: TrackId { - number: 01, - title: String::from("The Ecstasy of Gold"), - }, - artist: vec![String::from("Metallica")], - quality: Quality { - format: Format::Flac, - bitrate: 875, - }, - }, - Track { - id: TrackId { - number: 02, - title: String::from("The Call of Ktulu"), - }, - artist: vec![String::from("Metallica")], - quality: Quality { - format: Format::Flac, - bitrate: 1030, - }, - }, - Track { - id: TrackId { - number: 03, - title: String::from("Master of Puppets"), - }, - artist: vec![String::from("Metallica")], - quality: Quality { - format: Format::Flac, - bitrate: 1082, - }, - }, - Track { - id: TrackId { - number: 04, - title: String::from("Of Wolf and Man"), - }, - artist: vec![String::from("Metallica")], - quality: Quality { - format: Format::Flac, - bitrate: 1115, - }, - }, - Track { - id: TrackId { - number: 05, - title: String::from("The Thing That Should Not Be"), - }, - artist: vec![String::from("Metallica")], - quality: Quality { - format: Format::Flac, - bitrate: 1029, - }, - }, - Track { - id: TrackId { - number: 06, - title: String::from("Fuel"), - }, - artist: vec![String::from("Metallica")], - quality: Quality { - format: Format::Flac, - bitrate: 1057, - }, - }, - Track { - id: TrackId { - number: 07, - title: String::from("The Memory Remains"), - }, - artist: vec![String::from("Metallica")], - quality: Quality { - format: Format::Flac, - bitrate: 1080, - }, - }, - Track { - id: TrackId { - number: 08, - title: String::from("No Leaf Clover"), - }, - artist: vec![String::from("Metallica")], - quality: Quality { - format: Format::Flac, - bitrate: 1004, - }, - }, - Track { - id: TrackId { - number: 09, - title: String::from("Hero of the Day"), - }, - artist: vec![String::from("Metallica")], - quality: Quality { - format: Format::Flac, - bitrate: 962, - }, - }, - Track { - id: TrackId { - number: 10, - title: String::from("Devil’s Dance"), - }, - artist: vec![String::from("Metallica")], - quality: Quality { - format: Format::Flac, - bitrate: 1076, - }, - }, - Track { - id: TrackId { - number: 11, - title: String::from("Bleeding Me"), - }, - artist: vec![String::from("Metallica")], - quality: Quality { - format: Format::Flac, - bitrate: 993, - }, - }, - Track { - id: TrackId { - number: 12, - title: String::from("Nothing Else Matters"), - }, - artist: vec![String::from("Metallica")], - quality: Quality { - format: Format::Flac, - bitrate: 875, - }, - }, - Track { - id: TrackId { - number: 13, - title: String::from("Until It Sleeps"), - }, - artist: vec![String::from("Metallica")], - quality: Quality { - format: Format::Flac, - bitrate: 1038, - }, - }, - Track { - id: TrackId { - number: 14, - title: String::from("For Whom the Bell Tolls"), - }, - artist: vec![String::from("Metallica")], - quality: Quality { - format: Format::Flac, - bitrate: 1072, - }, - }, - Track { - id: TrackId { - number: 15, - title: String::from("−Human"), - }, - artist: vec![String::from("Metallica")], - quality: Quality { - format: Format::Flac, - bitrate: 1029, - }, - }, - Track { - id: TrackId { - number: 16, - title: String::from("Wherever I May Roam"), - }, - artist: vec![String::from("Metallica")], - quality: Quality { - format: Format::Flac, - bitrate: 1035, - }, - }, - Track { - id: TrackId { - number: 17, - title: String::from("Outlaw Torn"), - }, - artist: vec![String::from("Metallica")], - quality: Quality { - format: Format::Flac, - bitrate: 1042, - }, - }, - Track { - id: TrackId { - number: 18, - title: String::from("Sad but True"), - }, - artist: vec![String::from("Metallica")], - quality: Quality { - format: Format::Flac, - bitrate: 1082, - }, - }, - Track { - id: TrackId { - number: 19, - title: String::from("One"), - }, - artist: vec![String::from("Metallica")], - quality: Quality { - format: Format::Flac, - bitrate: 1017, - }, - }, - Track { - id: TrackId { - number: 20, - title: String::from("Enter Sandman"), - }, - artist: vec![String::from("Metallica")], - quality: Quality { - format: Format::Flac, - bitrate: 993, - }, - }, - Track { - id: TrackId { - number: 21, - title: String::from("Battery"), - }, - artist: vec![String::from("Metallica")], - quality: Quality { - format: Format::Flac, - bitrate: 967, - }, - }, - ], - }, - ], - }, - ] -}); +use musichoard::MusicHoard; + +use crate::testlib::COLLECTION; + +#[cfg(feature = "database-json")] +use musichoard::database::json::{backend::JsonDatabaseFileBackend, JsonDatabase}; + +#[cfg(feature = "library-beets")] +use musichoard::library::beets::{executor::BeetsLibraryProcessExecutor, BeetsLibrary}; + +#[test] +#[cfg(feature = "database-json")] +#[cfg(feature = "library-beets")] +fn merge_library_then_database() { + // Acquired the lock on the beets config file. We need to own the underlying object so later we + // create a new one. This is okay as the purpose of the lock is to prevent other tests to access + // the same Beets library at the same time. + let _arc = library::beets::BEETS_TEST_CONFIG.clone(); + let _ = &mut _arc.lock().unwrap(); + + let executor = BeetsLibraryProcessExecutor::default() + .config(Some(&*library::beets::BEETS_TEST_CONFIG_PATH)); + let library = BeetsLibrary::new(executor); + + let backend = JsonDatabaseFileBackend::new(&*database::json::DATABASE_TEST_FILE); + let database = JsonDatabase::new(backend); + + let mut music_hoard = MusicHoard::new(library, database); + + music_hoard.rescan_library().unwrap(); + music_hoard.load_from_database().unwrap(); + + assert_eq!(music_hoard.get_collection(), &*COLLECTION); +} + +#[test] +#[cfg(feature = "database-json")] +#[cfg(feature = "library-beets")] +fn merge_database_then_library() { + // Acquired the lock on the beets config file. We need to own the underlying object so later we + // create a new one. This is okay as the purpose of the lock is to prevent other tests to access + // the same Beets library at the same time. + let _arc = library::beets::BEETS_TEST_CONFIG.clone(); + let _ = &mut _arc.lock().unwrap(); + + let executor = BeetsLibraryProcessExecutor::default() + .config(Some(&*library::beets::BEETS_TEST_CONFIG_PATH)); + let library = BeetsLibrary::new(executor); + + let backend = JsonDatabaseFileBackend::new(&*database::json::DATABASE_TEST_FILE); + let database = JsonDatabase::new(backend); + + let mut music_hoard = MusicHoard::new(library, database); + + music_hoard.load_from_database().unwrap(); + music_hoard.rescan_library().unwrap(); + + assert_eq!(music_hoard.get_collection(), &*COLLECTION); +} diff --git a/tests/library/beets.rs b/tests/library/beets.rs index 6cd0f5c..dfe6853 100644 --- a/tests/library/beets.rs +++ b/tests/library/beets.rs @@ -1,7 +1,7 @@ use std::{ fs, path::PathBuf, - sync::{Arc, Mutex}, + sync::{Arc, Mutex}, collections::HashSet, }; use once_cell::sync::Lazy; @@ -14,21 +14,22 @@ use musichoard::{ Artist, }; -use crate::COLLECTION; +use crate::testlib::COLLECTION; -static BEETS_EMPTY_CONFIG: Lazy>>> = +pub static BEETS_TEST_CONFIG_PATH: Lazy = + Lazy::new(|| fs::canonicalize("./tests/files/library/config.yml").unwrap()); + +pub static BEETS_EMPTY_CONFIG: Lazy>>> = Lazy::new(|| { Arc::new(Mutex::new(BeetsLibrary::new( BeetsLibraryProcessExecutor::default(), ))) }); -static BEETS_TEST_CONFIG: Lazy>>> = +pub static BEETS_TEST_CONFIG: Lazy>>> = Lazy::new(|| { Arc::new(Mutex::new(BeetsLibrary::new( - BeetsLibraryProcessExecutor::default().config(Some( - &fs::canonicalize("./tests/files/library/config.yml").unwrap(), - )), + BeetsLibraryProcessExecutor::default().config(Some(&*BEETS_TEST_CONFIG_PATH)), ))) }); @@ -89,8 +90,10 @@ fn test_full_list() { let beets = &mut beets_arc.lock().unwrap(); let output = beets.list(&Query::new()).unwrap(); - let expected: Vec = artists_to_items(&COLLECTION); + + let output: HashSet<_> = output.iter().collect(); + let expected: HashSet<_> = expected.iter().collect(); assert_eq!(output, expected); } @@ -103,7 +106,7 @@ fn test_album_artist_query() { .list(Query::new().include(Field::AlbumArtist(String::from("Аркона")))) .unwrap(); - let expected: Vec = artists_to_items(&COLLECTION[0..1]); + let expected: Vec = artists_to_items(&COLLECTION[4..5]); assert_eq!(output, expected); } @@ -116,7 +119,7 @@ fn test_album_title_query() { .list(&Query::new().include(Field::AlbumTitle(String::from("Slovo")))) .unwrap(); - let expected: Vec = artists_to_items(&COLLECTION[0..1]); + let expected: Vec = artists_to_items(&COLLECTION[4..5]); assert_eq!(output, expected); } @@ -128,7 +131,9 @@ fn test_exclude_query() { let output = beets .list(&Query::new().exclude(Field::AlbumArtist(String::from("Аркона")))) .unwrap(); + let expected: Vec = artists_to_items(&COLLECTION[..4]); - let expected: Vec = artists_to_items(&COLLECTION[1..]); + let output: HashSet<_> = output.iter().collect(); + let expected: HashSet<_> = expected.iter().collect(); assert_eq!(output, expected); } diff --git a/tests/library/mod.rs b/tests/library/mod.rs index e2a7bee..d0ca87d 100644 --- a/tests/library/mod.rs +++ b/tests/library/mod.rs @@ -1,2 +1,2 @@ #[cfg(feature = "library-beets")] -mod beets; +pub mod beets; diff --git a/tests/testlib.rs b/tests/testlib.rs new file mode 100644 index 0000000..10745b3 --- /dev/null +++ b/tests/testlib.rs @@ -0,0 +1,1026 @@ +use musichoard::{ + Album, AlbumId, Artist, ArtistId, ArtistProperties, Bandcamp, Collection, Format, MusicBrainz, + MusicButler, Qobuz, Quality, Track, TrackId, +}; +use once_cell::sync::Lazy; + +pub static COLLECTION: Lazy> = Lazy::new(|| -> Collection { + vec![ + Artist { + id: ArtistId { + name: String::from("Eluveitie"), + }, + properties: ArtistProperties { + musicbrainz: Some(MusicBrainz::new( + "https://musicbrainz.org/artist/8000598a-5edb-401c-8e6d-36b167feaf38", + ).unwrap()), + musicbutler: vec![ + MusicButler::new("https://www.musicbutler.io/artist-page/269358403").unwrap(), + ], + bandcamp: vec![], + qobuz: Some(Qobuz::new( + "https://www.qobuz.com/nl-nl/interpreter/eluveitie/download-streaming-albums", + ).unwrap()), + }, + albums: vec![ + Album { + id: AlbumId { + year: 2004, + title: String::from("Vên [re‐recorded]"), + }, + tracks: vec![ + Track { + id: TrackId { + number: 01, + title: String::from("Verja Urit an Bitus"), + }, + artist: vec![String::from("Eluveitie")], + quality: Quality { + format: Format::Flac, + bitrate: 961, + }, + }, + Track { + id: TrackId { + number: 02, + title: String::from("Uis Elveti"), + }, + artist: vec![String::from("Eluveitie")], + quality: Quality { + format: Format::Flac, + bitrate: 1067, + }, + }, + Track { + id: TrackId { + number: 03, + title: String::from("Ôrô"), + }, + artist: vec![String::from("Eluveitie")], + quality: Quality { + format: Format::Flac, + bitrate: 933, + }, + }, + Track { + id: TrackId { + number: 04, + title: String::from("Lament"), + }, + artist: vec![String::from("Eluveitie")], + quality: Quality { + format: Format::Flac, + bitrate: 1083, + }, + }, + Track { + id: TrackId { + number: 05, + title: String::from("Druid"), + }, + artist: vec![String::from("Eluveitie")], + quality: Quality { + format: Format::Flac, + bitrate: 1073, + }, + }, + Track { + id: TrackId { + number: 06, + title: String::from("Jêzaïg"), + }, + artist: vec![String::from("Eluveitie")], + quality: Quality { + format: Format::Flac, + bitrate: 1002, + }, + }, + ], + }, + Album { + id: AlbumId { + year: 2008, + title: String::from("Slania"), + }, + tracks: vec![ + Track { + id: TrackId { + number: 01, + title: String::from("Samon"), + }, + artist: vec![String::from("Eluveitie")], + quality: Quality { + format: Format::Flac, + bitrate: 953, + }, + }, + Track { + id: TrackId { + number: 02, + title: String::from("Primordial Breath"), + }, + artist: vec![String::from("Eluveitie")], + quality: Quality { + format: Format::Flac, + bitrate: 1103, + }, + }, + Track { + id: TrackId { + number: 03, + title: String::from("Inis Mona"), + }, + artist: vec![String::from("Eluveitie")], + quality: Quality { + format: Format::Flac, + bitrate: 1117, + }, + }, + Track { + id: TrackId { + number: 04, + title: String::from("Gray Sublime Archon"), + }, + artist: vec![String::from("Eluveitie")], + quality: Quality { + format: Format::Flac, + bitrate: 1092, + }, + }, + Track { + id: TrackId { + number: 05, + title: String::from("Anagantios"), + }, + artist: vec![String::from("Eluveitie")], + quality: Quality { + format: Format::Flac, + bitrate: 923, + }, + }, + Track { + id: TrackId { + number: 06, + title: String::from("Bloodstained Ground"), + }, + artist: vec![String::from("Eluveitie")], + quality: Quality { + format: Format::Flac, + bitrate: 1098, + }, + }, + Track { + id: TrackId { + number: 07, + title: String::from("The Somber Lay"), + }, + artist: vec![String::from("Eluveitie")], + quality: Quality { + format: Format::Flac, + bitrate: 1068, + }, + }, + Track { + id: TrackId { + number: 08, + title: String::from("Slanias Song"), + }, + artist: vec![String::from("Eluveitie")], + quality: Quality { + format: Format::Flac, + bitrate: 1098, + }, + }, + Track { + id: TrackId { + number: 09, + title: String::from("Giamonios"), + }, + artist: vec![String::from("Eluveitie")], + quality: Quality { + format: Format::Flac, + bitrate: 825, + }, + }, + Track { + id: TrackId { + number: 10, + title: String::from("Tarvos"), + }, + artist: vec![String::from("Eluveitie")], + quality: Quality { + format: Format::Flac, + bitrate: 1115, + }, + }, + Track { + id: TrackId { + number: 11, + title: String::from("Calling the Rain"), + }, + artist: vec![String::from("Eluveitie")], + quality: Quality { + format: Format::Flac, + bitrate: 1096, + }, + }, + Track { + id: TrackId { + number: 12, + title: String::from("Elembivos"), + }, + artist: vec![String::from("Eluveitie")], + quality: Quality { + format: Format::Flac, + bitrate: 1059, + }, + }, + ], + }, + ], + }, + Artist { + id: ArtistId { + name: String::from("Frontside"), + }, + properties: ArtistProperties { + musicbrainz: Some(MusicBrainz::new( + "https://musicbrainz.org/artist/3a901353-fccd-4afd-ad01-9c03f451b490", + ).unwrap()), + musicbutler: vec![ + MusicButler::new("https://www.musicbutler.io/artist-page/826588800").unwrap(), + ], + bandcamp: vec![], + qobuz: Some(Qobuz::new( + "https://www.qobuz.com/nl-nl/interpreter/frontside/download-streaming-albums", + ).unwrap()), + }, + albums: vec![Album { + id: AlbumId { + year: 2001, + title: String::from("…nasze jest królestwo, potęga i chwała na wieki…"), + }, + tracks: vec![ + Track { + id: TrackId { + number: 01, + title: String::from("Intro = Chaos"), + }, + artist: vec![String::from("Frontside")], + quality: Quality { + format: Format::Flac, + bitrate: 1024, + }, + }, + Track { + id: TrackId { + number: 02, + title: String::from("Modlitwa"), + }, + artist: vec![String::from("Frontside")], + quality: Quality { + format: Format::Flac, + bitrate: 1073, + }, + }, + Track { + id: TrackId { + number: 03, + title: String::from("Długa droga z piekła"), + }, + artist: vec![String::from("Frontside")], + quality: Quality { + format: Format::Flac, + bitrate: 1058, + }, + }, + Track { + id: TrackId { + number: 04, + title: String::from("Synowie ognia"), + }, + artist: vec![String::from("Frontside")], + quality: Quality { + format: Format::Flac, + bitrate: 1066, + }, + }, + Track { + id: TrackId { + number: 05, + title: String::from("1902"), + }, + artist: vec![String::from("Frontside")], + quality: Quality { + format: Format::Flac, + bitrate: 1074, + }, + }, + Track { + id: TrackId { + number: 06, + title: String::from("Krew za krew"), + }, + artist: vec![String::from("Frontside")], + quality: Quality { + format: Format::Flac, + bitrate: 1080, + }, + }, + Track { + id: TrackId { + number: 07, + title: String::from("Kulminacja"), + }, + artist: vec![String::from("Frontside")], + quality: Quality { + format: Format::Flac, + bitrate: 992, + }, + }, + Track { + id: TrackId { + number: 08, + title: String::from("Judasz"), + }, + artist: vec![String::from("Frontside")], + quality: Quality { + format: Format::Flac, + bitrate: 1018, + }, + }, + Track { + id: TrackId { + number: 09, + title: String::from("Więzy"), + }, + artist: vec![String::from("Frontside")], + quality: Quality { + format: Format::Flac, + bitrate: 1077, + }, + }, + Track { + id: TrackId { + number: 10, + title: String::from("Zagubione dusze"), + }, + artist: vec![String::from("Frontside")], + quality: Quality { + format: Format::Flac, + bitrate: 1033, + }, + }, + Track { + id: TrackId { + number: 11, + title: String::from("Linia życia"), + }, + artist: vec![String::from("Frontside")], + quality: Quality { + format: Format::Flac, + bitrate: 987, + }, + }, + ], + }], + }, + Artist { + id: ArtistId { + name: String::from("Heaven’s Basement"), + }, + properties: ArtistProperties { + musicbrainz: Some(MusicBrainz::new( + "https://musicbrainz.org/artist/c2c4d56a-d599-4a18-bd2f-ae644e2198cc", + ).unwrap()), + musicbutler: vec![ + MusicButler::new("https://www.musicbutler.io/artist-page/291158685").unwrap(), + ], + bandcamp: vec![], + qobuz: Some(Qobuz::new( + "https://www.qobuz.com/nl-nl/interpreter/heaven-s-basement/download-streaming-albums", + ).unwrap()), + }, + albums: vec![Album { + id: AlbumId { + year: 2011, + title: String::from("Unbreakable"), + }, + tracks: vec![ + Track { + id: TrackId { + number: 01, + title: String::from("Unbreakable"), + }, + artist: vec![String::from("Heaven’s Basement")], + quality: Quality { + format: Format::Mp3, + bitrate: 208, + }, + }, + Track { + id: TrackId { + number: 02, + title: String::from("Guilt Trips and Sins"), + }, + artist: vec![String::from("Heaven’s Basement")], + quality: Quality { + format: Format::Mp3, + bitrate: 205, + }, + }, + Track { + id: TrackId { + number: 03, + title: String::from("The Long Goodbye"), + }, + artist: vec![String::from("Heaven’s Basement")], + quality: Quality { + format: Format::Mp3, + bitrate: 227, + }, + }, + Track { + id: TrackId { + number: 04, + title: String::from("Close Encounters"), + }, + artist: vec![String::from("Heaven’s Basement")], + quality: Quality { + format: Format::Mp3, + bitrate: 213, + }, + }, + Track { + id: TrackId { + number: 05, + title: String::from("Paranoia"), + }, + artist: vec![String::from("Heaven’s Basement")], + quality: Quality { + format: Format::Mp3, + bitrate: 218, + }, + }, + Track { + id: TrackId { + number: 06, + title: String::from("Let Me Out of Here"), + }, + artist: vec![String::from("Heaven’s Basement")], + quality: Quality { + format: Format::Mp3, + bitrate: 207, + }, + }, + Track { + id: TrackId { + number: 07, + title: String::from("Leeches"), + }, + artist: vec![String::from("Heaven’s Basement")], + quality: Quality { + format: Format::Mp3, + bitrate: 225, + }, + }, + ], + }], + }, + Artist { + id: ArtistId { + name: String::from("Metallica"), + }, + properties: ArtistProperties { + musicbrainz: Some(MusicBrainz::new( + "https://musicbrainz.org/artist/65f4f0c5-ef9e-490c-aee3-909e7ae6b2ab", + ).unwrap()), + musicbutler: vec![ + MusicButler::new("https://www.musicbutler.io/artist-page/3996865").unwrap(), + ], + bandcamp: vec![], + qobuz: Some(Qobuz::new( + "https://www.qobuz.com/nl-nl/interpreter/metallica/download-streaming-albums", + ).unwrap()), + }, + albums: vec![ + Album { + id: AlbumId { + year: 1984, + title: String::from("Ride the Lightning"), + }, + tracks: vec![ + Track { + id: TrackId { + number: 01, + title: String::from("Fight Fire with Fire"), + }, + artist: vec![String::from("Metallica")], + quality: Quality { + format: Format::Flac, + bitrate: 954, + }, + }, + Track { + id: TrackId { + number: 02, + title: String::from("Ride the Lightning"), + }, + artist: vec![String::from("Metallica")], + quality: Quality { + format: Format::Flac, + bitrate: 951, + }, + }, + Track { + id: TrackId { + number: 03, + title: String::from("For Whom the Bell Tolls"), + }, + artist: vec![String::from("Metallica")], + quality: Quality { + format: Format::Flac, + bitrate: 889, + }, + }, + Track { + id: TrackId { + number: 04, + title: String::from("Fade to Black"), + }, + artist: vec![String::from("Metallica")], + quality: Quality { + format: Format::Flac, + bitrate: 939, + }, + }, + Track { + id: TrackId { + number: 05, + title: String::from("Trapped under Ice"), + }, + artist: vec![String::from("Metallica")], + quality: Quality { + format: Format::Flac, + bitrate: 955, + }, + }, + Track { + id: TrackId { + number: 06, + title: String::from("Escape"), + }, + artist: vec![String::from("Metallica")], + quality: Quality { + format: Format::Flac, + bitrate: 941, + }, + }, + Track { + id: TrackId { + number: 07, + title: String::from("Creeping Death"), + }, + artist: vec![String::from("Metallica")], + quality: Quality { + format: Format::Flac, + bitrate: 958, + }, + }, + Track { + id: TrackId { + number: 08, + title: String::from("The Call of Ktulu"), + }, + artist: vec![String::from("Metallica")], + quality: Quality { + format: Format::Flac, + bitrate: 888, + }, + }, + ], + }, + Album { + id: AlbumId { + year: 1999, + title: String::from("S&M"), + }, + tracks: vec![ + Track { + id: TrackId { + number: 01, + title: String::from("The Ecstasy of Gold"), + }, + artist: vec![String::from("Metallica")], + quality: Quality { + format: Format::Flac, + bitrate: 875, + }, + }, + Track { + id: TrackId { + number: 02, + title: String::from("The Call of Ktulu"), + }, + artist: vec![String::from("Metallica")], + quality: Quality { + format: Format::Flac, + bitrate: 1030, + }, + }, + Track { + id: TrackId { + number: 03, + title: String::from("Master of Puppets"), + }, + artist: vec![String::from("Metallica")], + quality: Quality { + format: Format::Flac, + bitrate: 1082, + }, + }, + Track { + id: TrackId { + number: 04, + title: String::from("Of Wolf and Man"), + }, + artist: vec![String::from("Metallica")], + quality: Quality { + format: Format::Flac, + bitrate: 1115, + }, + }, + Track { + id: TrackId { + number: 05, + title: String::from("The Thing That Should Not Be"), + }, + artist: vec![String::from("Metallica")], + quality: Quality { + format: Format::Flac, + bitrate: 1029, + }, + }, + Track { + id: TrackId { + number: 06, + title: String::from("Fuel"), + }, + artist: vec![String::from("Metallica")], + quality: Quality { + format: Format::Flac, + bitrate: 1057, + }, + }, + Track { + id: TrackId { + number: 07, + title: String::from("The Memory Remains"), + }, + artist: vec![String::from("Metallica")], + quality: Quality { + format: Format::Flac, + bitrate: 1080, + }, + }, + Track { + id: TrackId { + number: 08, + title: String::from("No Leaf Clover"), + }, + artist: vec![String::from("Metallica")], + quality: Quality { + format: Format::Flac, + bitrate: 1004, + }, + }, + Track { + id: TrackId { + number: 09, + title: String::from("Hero of the Day"), + }, + artist: vec![String::from("Metallica")], + quality: Quality { + format: Format::Flac, + bitrate: 962, + }, + }, + Track { + id: TrackId { + number: 10, + title: String::from("Devil’s Dance"), + }, + artist: vec![String::from("Metallica")], + quality: Quality { + format: Format::Flac, + bitrate: 1076, + }, + }, + Track { + id: TrackId { + number: 11, + title: String::from("Bleeding Me"), + }, + artist: vec![String::from("Metallica")], + quality: Quality { + format: Format::Flac, + bitrate: 993, + }, + }, + Track { + id: TrackId { + number: 12, + title: String::from("Nothing Else Matters"), + }, + artist: vec![String::from("Metallica")], + quality: Quality { + format: Format::Flac, + bitrate: 875, + }, + }, + Track { + id: TrackId { + number: 13, + title: String::from("Until It Sleeps"), + }, + artist: vec![String::from("Metallica")], + quality: Quality { + format: Format::Flac, + bitrate: 1038, + }, + }, + Track { + id: TrackId { + number: 14, + title: String::from("For Whom the Bell Tolls"), + }, + artist: vec![String::from("Metallica")], + quality: Quality { + format: Format::Flac, + bitrate: 1072, + }, + }, + Track { + id: TrackId { + number: 15, + title: String::from("−Human"), + }, + artist: vec![String::from("Metallica")], + quality: Quality { + format: Format::Flac, + bitrate: 1029, + }, + }, + Track { + id: TrackId { + number: 16, + title: String::from("Wherever I May Roam"), + }, + artist: vec![String::from("Metallica")], + quality: Quality { + format: Format::Flac, + bitrate: 1035, + }, + }, + Track { + id: TrackId { + number: 17, + title: String::from("Outlaw Torn"), + }, + artist: vec![String::from("Metallica")], + quality: Quality { + format: Format::Flac, + bitrate: 1042, + }, + }, + Track { + id: TrackId { + number: 18, + title: String::from("Sad but True"), + }, + artist: vec![String::from("Metallica")], + quality: Quality { + format: Format::Flac, + bitrate: 1082, + }, + }, + Track { + id: TrackId { + number: 19, + title: String::from("One"), + }, + artist: vec![String::from("Metallica")], + quality: Quality { + format: Format::Flac, + bitrate: 1017, + }, + }, + Track { + id: TrackId { + number: 20, + title: String::from("Enter Sandman"), + }, + artist: vec![String::from("Metallica")], + quality: Quality { + format: Format::Flac, + bitrate: 993, + }, + }, + Track { + id: TrackId { + number: 21, + title: String::from("Battery"), + }, + artist: vec![String::from("Metallica")], + quality: Quality { + format: Format::Flac, + bitrate: 967, + }, + }, + ], + }, + ], + }, + Artist { + id: ArtistId { + name: String::from("Аркона"), + }, + properties: ArtistProperties { + musicbrainz: Some(MusicBrainz::new( + "https://musicbrainz.org/artist/baad262d-55ef-427a-83c7-f7530964f212", + ).unwrap()), + musicbutler: vec![ + MusicButler::new("https://www.musicbutler.io/artist-page/283448581").unwrap(), + ], + bandcamp: vec![ + Bandcamp::new("https://arkonamoscow.bandcamp.com/").unwrap(), + ], + qobuz: Some(Qobuz::new( + "https://www.qobuz.com/nl-nl/interpreter/arkona/download-streaming-albums", + ).unwrap()), + }, + albums: vec![Album { + id: AlbumId { + year: 2011, + title: String::from("Slovo"), + }, + tracks: vec![ + Track { + id: TrackId { + number: 01, + title: String::from("Az’"), + }, + artist: vec![String::from("Аркона")], + quality: Quality { + format: Format::Flac, + bitrate: 992, + }, + }, + Track { + id: TrackId { + number: 02, + title: String::from("Arkaim"), + }, + artist: vec![String::from("Аркона")], + quality: Quality { + format: Format::Flac, + bitrate: 1061, + }, + }, + Track { + id: TrackId { + number: 03, + title: String::from("Bol’no mne"), + }, + artist: vec![String::from("Аркона")], + quality: Quality { + format: Format::Flac, + bitrate: 1004, + }, + }, + Track { + id: TrackId { + number: 04, + title: String::from("Leshiy"), + }, + artist: vec![String::from("Аркона")], + quality: Quality { + format: Format::Flac, + bitrate: 1077, + }, + }, + Track { + id: TrackId { + number: 05, + title: String::from("Zakliatie"), + }, + artist: vec![String::from("Аркона")], + quality: Quality { + format: Format::Flac, + bitrate: 1041, + }, + }, + Track { + id: TrackId { + number: 06, + title: String::from("Predok"), + }, + artist: vec![String::from("Аркона")], + quality: Quality { + format: Format::Flac, + bitrate: 756, + }, + }, + Track { + id: TrackId { + number: 07, + title: String::from("Nikogda"), + }, + artist: vec![String::from("Аркона")], + quality: Quality { + format: Format::Flac, + bitrate: 1059, + }, + }, + Track { + id: TrackId { + number: 08, + title: String::from("Tam za tumanami"), + }, + artist: vec![String::from("Аркона")], + quality: Quality { + format: Format::Flac, + bitrate: 1023, + }, + }, + Track { + id: TrackId { + number: 09, + title: String::from("Potomok"), + }, + artist: vec![String::from("Аркона")], + quality: Quality { + format: Format::Flac, + bitrate: 838, + }, + }, + Track { + id: TrackId { + number: 10, + title: String::from("Slovo"), + }, + artist: vec![String::from("Аркона")], + quality: Quality { + format: Format::Flac, + bitrate: 1028, + }, + }, + Track { + id: TrackId { + number: 11, + title: String::from("Odna"), + }, + artist: vec![String::from("Аркона")], + quality: Quality { + format: Format::Flac, + bitrate: 991, + }, + }, + Track { + id: TrackId { + number: 12, + title: String::from("Vo moiom sadochke…"), + }, + artist: vec![String::from("Аркона")], + quality: Quality { + format: Format::Flac, + bitrate: 919, + }, + }, + Track { + id: TrackId { + number: 13, + title: String::from("Stenka na stenku"), + }, + artist: vec![String::from("Аркона")], + quality: Quality { + format: Format::Flac, + bitrate: 1039, + }, + }, + Track { + id: TrackId { + number: 14, + title: String::from("Zimushka"), + }, + artist: vec![String::from("Аркона")], + quality: Quality { + format: Format::Flac, + bitrate: 974, + }, + }, + ], + }], + }, + ] +});