Sort albums by month if two releases of the same artist happen in the same year #155

Merged
6 changed files with 56 additions and 51 deletions
Showing only changes of commit bb060770b4 - Show all commits

View File

@ -41,8 +41,8 @@ impl Artist {
}
}
pub fn get_sort_key(&self) -> &ArtistId {
self.sort.as_ref().unwrap_or(&self.id)
pub fn get_sort_key(&self) -> (&ArtistId,) {
(self.sort.as_ref().unwrap_or(&self.id),)
}
pub fn set_sort_key<SORT: Into<ArtistId>>(&mut self, sort: SORT) {
@ -114,7 +114,7 @@ impl PartialOrd for Artist {
impl Ord for Artist {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.get_sort_key().cmp(other.get_sort_key())
self.get_sort_key().cmp(&other.get_sort_key())
}
}
@ -260,7 +260,7 @@ mod tests {
assert_eq!(artist.id, artist_id);
assert_eq!(artist.sort, None);
assert_eq!(artist.get_sort_key(), &artist_id);
assert_eq!(artist.get_sort_key(), (&artist_id,));
assert!(artist < Artist::new(sort_id_1.clone()));
assert!(artist < Artist::new(sort_id_2.clone()));
@ -268,7 +268,7 @@ mod tests {
assert_eq!(artist.id, artist_id);
assert_eq!(artist.sort.as_ref(), Some(&sort_id_1));
assert_eq!(artist.get_sort_key(), &sort_id_1);
assert_eq!(artist.get_sort_key(), (&sort_id_1,));
assert!(artist > Artist::new(artist_id.clone()));
assert!(artist < Artist::new(sort_id_2.clone()));
@ -276,7 +276,7 @@ mod tests {
assert_eq!(artist.id, artist_id);
assert_eq!(artist.sort.as_ref(), Some(&sort_id_2));
assert_eq!(artist.get_sort_key(), &sort_id_2);
assert_eq!(artist.get_sort_key(), (&sort_id_2,));
assert!(artist > Artist::new(artist_id.clone()));
assert!(artist > Artist::new(sort_id_1.clone()));
@ -284,7 +284,7 @@ mod tests {
assert_eq!(artist.id, artist_id);
assert_eq!(artist.sort, None);
assert_eq!(artist.get_sort_key(), &artist_id);
assert_eq!(artist.get_sort_key(), (&artist_id,));
assert!(artist < Artist::new(sort_id_1.clone()));
assert!(artist < Artist::new(sort_id_2.clone()));
}

View File

@ -1,7 +1,7 @@
use crate::tui::{
app::{
machine::{App, AppInner, AppMachine},
selection::IdSelection,
selection::KeySelection,
AppPublic, AppState, IAppInteractReload,
},
lib::IMusicHoard,
@ -36,7 +36,7 @@ impl<MH: IMusicHoard> IAppInteractReload for AppMachine<MH, AppReload> {
type APP = App<MH>;
fn reload_library(mut self) -> Self::APP {
let previous = IdSelection::get(
let previous = KeySelection::get(
self.inner.music_hoard.get_collection(),
&self.inner.selection,
);
@ -45,7 +45,7 @@ impl<MH: IMusicHoard> IAppInteractReload for AppMachine<MH, AppReload> {
}
fn reload_database(mut self) -> Self::APP {
let previous = IdSelection::get(
let previous = KeySelection::get(
self.inner.music_hoard.get_collection(),
&self.inner.selection,
);
@ -63,11 +63,11 @@ impl<MH: IMusicHoard> IAppInteractReload for AppMachine<MH, AppReload> {
}
trait IAppInteractReloadPrivate<MH: IMusicHoard> {
fn refresh(self, previous: IdSelection, result: Result<(), musichoard::Error>) -> App<MH>;
fn refresh(self, previous: KeySelection, result: Result<(), musichoard::Error>) -> App<MH>;
}
impl<MH: IMusicHoard> IAppInteractReloadPrivate<MH> for AppMachine<MH, AppReload> {
fn refresh(mut self, previous: IdSelection, result: Result<(), musichoard::Error>) -> App<MH> {
fn refresh(mut self, previous: KeySelection, result: Result<(), musichoard::Error>) -> App<MH> {
match result {
Ok(()) => {
self.inner

View File

@ -6,7 +6,7 @@ use musichoard::collection::{
};
use crate::tui::app::selection::{
track::{IdSelectTrack, TrackSelection},
track::{KeySelectTrack, TrackSelection},
Delta, SelectionState, WidgetState,
};
@ -26,7 +26,7 @@ impl AlbumSelection {
selection
}
pub fn reinitialise(&mut self, albums: &[Album], album: Option<IdSelectAlbum>) {
pub fn reinitialise(&mut self, albums: &[Album], album: Option<KeySelectAlbum>) {
if let Some(album) = album {
let result = albums.binary_search_by(|a| a.get_sort_key().cmp(&album.get_sort_key()));
match result {
@ -42,7 +42,7 @@ impl AlbumSelection {
&mut self,
albums: &[Album],
index: usize,
active_track: Option<IdSelectTrack>,
active_track: Option<KeySelectTrack>,
) {
if albums.is_empty() {
self.state.list.select(None);
@ -160,19 +160,19 @@ impl AlbumSelection {
}
}
pub struct IdSelectAlbum {
pub struct KeySelectAlbum {
key: (AlbumDate, AlbumSeq, AlbumId),
track: Option<IdSelectTrack>,
track: Option<KeySelectTrack>,
}
impl IdSelectAlbum {
impl KeySelectAlbum {
pub fn get(albums: &[Album], selection: &AlbumSelection) -> Option<Self> {
selection.state.list.selected().map(|index| {
let album = &albums[index];
let key = album.get_sort_key();
IdSelectAlbum {
KeySelectAlbum {
key: (key.0.to_owned(), key.1.to_owned(), key.2.to_owned()),
track: IdSelectTrack::get(&album.tracks, &selection.track),
track: KeySelectTrack::get(&album.tracks, &selection.track),
}
})
}
@ -335,20 +335,20 @@ mod tests {
// Re-initialise.
let expected = sel.clone();
let active_album = IdSelectAlbum::get(albums, &sel);
let active_album = KeySelectAlbum::get(albums, &sel);
sel.reinitialise(albums, active_album);
assert_eq!(sel, expected);
// Re-initialise out-of-bounds.
let mut expected = sel.clone();
expected.decrement(albums, Delta::Line);
let active_album = IdSelectAlbum::get(albums, &sel);
let active_album = KeySelectAlbum::get(albums, &sel);
sel.reinitialise(&albums[..(albums.len() - 1)], active_album);
assert_eq!(sel, expected);
// Re-initialise empty.
let expected = AlbumSelection::initialise(&[]);
let active_album = IdSelectAlbum::get(albums, &sel);
let active_album = KeySelectAlbum::get(albums, &sel);
sel.reinitialise(&[], active_album);
assert_eq!(sel, expected);
}

View File

@ -7,7 +7,7 @@ use musichoard::collection::{
};
use crate::tui::app::selection::{
album::{AlbumSelection, IdSelectAlbum},
album::{AlbumSelection, KeySelectAlbum},
Delta, SelectionState, WidgetState,
};
@ -27,9 +27,9 @@ impl ArtistSelection {
selection
}
pub fn reinitialise(&mut self, artists: &[Artist], active: Option<IdSelectArtist>) {
pub fn reinitialise(&mut self, artists: &[Artist], active: Option<KeySelectArtist>) {
if let Some(active) = active {
let result = artists.binary_search_by(|a| a.get_sort_key().cmp(&active.artist_id));
let result = artists.binary_search_by(|a| a.get_sort_key().cmp(&active.get_sort_key()));
match result {
Ok(index) => self.reinitialise_with_index(artists, index, active.album),
Err(index) => self.reinitialise_with_index(artists, index, None),
@ -43,7 +43,7 @@ impl ArtistSelection {
&mut self,
artists: &[Artist],
index: usize,
active_album: Option<IdSelectAlbum>,
active_album: Option<KeySelectAlbum>,
) {
if artists.is_empty() {
self.state.list.select(None);
@ -193,21 +193,26 @@ impl ArtistSelection {
}
}
pub struct IdSelectArtist {
artist_id: ArtistId,
album: Option<IdSelectAlbum>,
pub struct KeySelectArtist {
key: (ArtistId,),
album: Option<KeySelectAlbum>,
}
impl IdSelectArtist {
impl KeySelectArtist {
pub fn get(artists: &[Artist], selection: &ArtistSelection) -> Option<Self> {
selection.state.list.selected().map(|index| {
let artist = &artists[index];
IdSelectArtist {
artist_id: artist.get_sort_key().clone(),
album: IdSelectAlbum::get(&artist.albums, &selection.album),
let key = artist.get_sort_key();
KeySelectArtist {
key: (key.0.to_owned(),),
album: KeySelectAlbum::get(&artist.albums, &selection.album),
}
})
}
pub fn get_sort_key(&self) -> (&ArtistId,) {
(&self.key.0,)
}
}
#[cfg(test)]
@ -385,20 +390,20 @@ mod tests {
// Re-initialise.
let expected = sel.clone();
let active_artist = IdSelectArtist::get(artists, &sel);
let active_artist = KeySelectArtist::get(artists, &sel);
sel.reinitialise(artists, active_artist);
assert_eq!(sel, expected);
// Re-initialise out-of-bounds.
let mut expected = sel.clone();
expected.decrement(artists, Delta::Line);
let active_artist = IdSelectArtist::get(artists, &sel);
let active_artist = KeySelectArtist::get(artists, &sel);
sel.reinitialise(&artists[..(artists.len() - 1)], active_artist);
assert_eq!(sel, expected);
// Re-initialise empty.
let expected = ArtistSelection::initialise(&[]);
let active_artist = IdSelectArtist::get(artists, &sel);
let active_artist = KeySelectArtist::get(artists, &sel);
sel.reinitialise(&[], active_artist);
assert_eq!(sel, expected);
}

View File

@ -5,7 +5,7 @@ mod track;
use musichoard::collection::{album::Album, artist::Artist, track::Track, Collection};
use ratatui::widgets::ListState;
use artist::{ArtistSelection, IdSelectArtist};
use artist::{ArtistSelection, KeySelectArtist};
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Category {
@ -64,7 +64,7 @@ impl Selection {
self.artist.album.track.state.list = selected.track;
}
pub fn select_by_id(&mut self, artists: &[Artist], selected: IdSelection) {
pub fn select_by_id(&mut self, artists: &[Artist], selected: KeySelection) {
self.artist.reinitialise(artists, selected.artist);
}
@ -229,14 +229,14 @@ impl ListSelection {
}
}
pub struct IdSelection {
artist: Option<IdSelectArtist>,
pub struct KeySelection {
artist: Option<KeySelectArtist>,
}
impl IdSelection {
impl KeySelection {
pub fn get(collection: &Collection, selection: &Selection) -> Self {
IdSelection {
artist: IdSelectArtist::get(collection, &selection.artist),
KeySelection {
artist: KeySelectArtist::get(collection, &selection.artist),
}
}
}

View File

@ -18,7 +18,7 @@ impl TrackSelection {
selection
}
pub fn reinitialise(&mut self, tracks: &[Track], track: Option<IdSelectTrack>) {
pub fn reinitialise(&mut self, tracks: &[Track], track: Option<KeySelectTrack>) {
if let Some(track) = track {
let result = tracks.binary_search_by(|t| t.get_sort_key().cmp(&track.get_sort_key()));
match result {
@ -100,16 +100,16 @@ impl TrackSelection {
}
}
pub struct IdSelectTrack {
pub struct KeySelectTrack {
key: (TrackNum, TrackId),
}
impl IdSelectTrack {
impl KeySelectTrack {
pub fn get(tracks: &[Track], selection: &TrackSelection) -> Option<Self> {
selection.state.list.selected().map(|index| {
let track = &tracks[index];
let key = track.get_sort_key();
IdSelectTrack {
KeySelectTrack {
key: (key.0.to_owned(), key.1.to_owned()),
}
})
@ -215,20 +215,20 @@ mod tests {
// Re-initialise.
let expected = sel.clone();
let active_track = IdSelectTrack::get(tracks, &sel);
let active_track = KeySelectTrack::get(tracks, &sel);
sel.reinitialise(tracks, active_track);
assert_eq!(sel, expected);
// Re-initialise out-of-bounds.
let mut expected = sel.clone();
expected.decrement(tracks, Delta::Line);
let active_track = IdSelectTrack::get(tracks, &sel);
let active_track = KeySelectTrack::get(tracks, &sel);
sel.reinitialise(&tracks[..(tracks.len() - 1)], active_track);
assert_eq!(sel, expected);
// Re-initialise empty.
let expected = TrackSelection::initialise(&[]);
let active_track = IdSelectTrack::get(tracks, &sel);
let active_track = KeySelectTrack::get(tracks, &sel);
sel.reinitialise(&[], active_track);
assert_eq!(sel, expected);
}