diff --git a/src/lib.rs b/src/lib.rs index 1819ea3..e356f84 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -39,8 +39,24 @@ pub struct Track { pub quality: Quality, } +impl PartialOrd for Track { + fn partial_cmp(&self, other: &Self) -> Option { + let id = (&self.number, &self.title); + let other_id = (&other.number, &other.title); + id.partial_cmp(&other_id) + } +} + +impl Ord for Track { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + let id = (&self.number, &self.title); + let other_id = (&other.number, &other.title); + id.cmp(&other_id) + } +} + /// The album identifier. -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, Hash)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, PartialOrd, Ord, Eq, Hash)] pub struct AlbumId { pub year: u32, pub title: String, @@ -53,8 +69,20 @@ pub struct Album { pub tracks: Vec, } +impl PartialOrd for Album { + fn partial_cmp(&self, other: &Self) -> Option { + self.id.partial_cmp(&other.id) + } +} + +impl Ord for Album { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.id.cmp(&other.id) + } +} + /// The artist identifier. -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, Hash)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct ArtistId { pub name: String, } @@ -66,6 +94,18 @@ pub struct Artist { pub albums: Vec, } +impl PartialOrd for Artist { + fn partial_cmp(&self, other: &Self) -> Option { + self.id.partial_cmp(&other.id) + } +} + +impl Ord for Artist { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.id.cmp(&other.id) + } +} + /// The collection type. Currently, a collection is a list of artists. pub type Collection = Vec; @@ -122,6 +162,7 @@ impl MusicHoard { pub fn rescan_library(&mut self) -> Result<(), Error> { let items = self.library.list(&Query::new())?; self.collection = Self::items_to_artists(items); + Self::sort(&mut self.collection); Ok(()) } @@ -134,6 +175,16 @@ impl MusicHoard { &self.collection } + fn sort(collection: &mut [Artist]) { + collection.sort_unstable(); + for artist in collection.iter_mut() { + artist.albums.sort_unstable(); + for album in artist.albums.iter_mut() { + album.tracks.sort_unstable(); + } + } + } + fn items_to_artists(items: Vec) -> Vec { let mut artists: Vec = vec![]; let mut album_ids = HashMap::>::new(); @@ -287,23 +338,8 @@ mod tests { let mut music_hoard = MusicHoard::new(library, database); - let mut expected = COLLECTION.to_owned(); - - // Putting the last track first will make the entire artist come first in the output. - expected.rotate_right(1); - - // Same applies to that artists' albums. - expected[0].albums.rotate_right(1); - - // Same applies to that album's tracks. - expected[0].albums[0].tracks.rotate_right(1); - - // And the original first album's (now the first album of the second artist) tracks first - // track comes last as it will only get picked up at the end. - expected[1].albums[0].tracks.rotate_left(1); - music_hoard.rescan_library().unwrap(); - assert_eq!(music_hoard.get_collection(), &expected); + assert_eq!(music_hoard.get_collection(), &*COLLECTION); } #[test]