Sort the collection
This commit is contained in:
parent
847a6dcf9c
commit
cc4e59a76e
72
src/lib.rs
72
src/lib.rs
@ -39,8 +39,24 @@ pub struct Track {
|
|||||||
pub quality: Quality,
|
pub quality: Quality,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PartialOrd for Track {
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||||
|
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.
|
/// 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 struct AlbumId {
|
||||||
pub year: u32,
|
pub year: u32,
|
||||||
pub title: String,
|
pub title: String,
|
||||||
@ -53,8 +69,20 @@ pub struct Album {
|
|||||||
pub tracks: Vec<Track>,
|
pub tracks: Vec<Track>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PartialOrd for Album {
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||||
|
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.
|
/// 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 struct ArtistId {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
}
|
}
|
||||||
@ -66,6 +94,18 @@ pub struct Artist {
|
|||||||
pub albums: Vec<Album>,
|
pub albums: Vec<Album>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PartialOrd for Artist {
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||||
|
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.
|
/// The collection type. Currently, a collection is a list of artists.
|
||||||
pub type Collection = Vec<Artist>;
|
pub type Collection = Vec<Artist>;
|
||||||
|
|
||||||
@ -122,6 +162,7 @@ impl<LIB: ILibrary, DB: IDatabase> MusicHoard<LIB, DB> {
|
|||||||
pub fn rescan_library(&mut self) -> Result<(), Error> {
|
pub fn rescan_library(&mut self) -> Result<(), Error> {
|
||||||
let items = self.library.list(&Query::new())?;
|
let items = self.library.list(&Query::new())?;
|
||||||
self.collection = Self::items_to_artists(items);
|
self.collection = Self::items_to_artists(items);
|
||||||
|
Self::sort(&mut self.collection);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,6 +175,16 @@ impl<LIB: ILibrary, DB: IDatabase> MusicHoard<LIB, DB> {
|
|||||||
&self.collection
|
&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<Item>) -> Vec<Artist> {
|
fn items_to_artists(items: Vec<Item>) -> Vec<Artist> {
|
||||||
let mut artists: Vec<Artist> = vec![];
|
let mut artists: Vec<Artist> = vec![];
|
||||||
let mut album_ids = HashMap::<ArtistId, HashSet<AlbumId>>::new();
|
let mut album_ids = HashMap::<ArtistId, HashSet<AlbumId>>::new();
|
||||||
@ -287,23 +338,8 @@ mod tests {
|
|||||||
|
|
||||||
let mut music_hoard = MusicHoard::new(library, database);
|
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();
|
music_hoard.rescan_library().unwrap();
|
||||||
assert_eq!(music_hoard.get_collection(), &expected);
|
assert_eq!(music_hoard.get_collection(), &*COLLECTION);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
Loading…
Reference in New Issue
Block a user