From 6ab3823acd04837cceb7efaca84eb31f517c426c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Toma=C5=9Bko?= Date: Wed, 21 Aug 2024 14:09:10 +0200 Subject: [PATCH] Replace `find::songs_from_album` with helper fns Map->Vec --- endsong_ui/src/main.rs | 2 +- endsong_ui/src/ui/mod.rs | 6 +----- src/entry.rs | 10 ---------- src/find.rs | 32 ++++++++++++++++++-------------- src/gather.rs | 14 +++++++++++++- src/lib.rs | 30 ++++++++++++++++++++++++++++++ 6 files changed, 63 insertions(+), 31 deletions(-) diff --git a/endsong_ui/src/main.rs b/endsong_ui/src/main.rs index 7179c19..0673061 100644 --- a/endsong_ui/src/main.rs +++ b/endsong_ui/src/main.rs @@ -146,7 +146,7 @@ fn test_two(entries: &SongEntries) { let ct = Album::new("Waking The Fallen", "Avenged Sevenfold"); let mut alb_dur = TimeDelta::try_seconds(0).unwrap(); - let ct_songs = entries.find().songs_from_album(&ct); + let ct_songs = get_sorted_list(gather::songs_from(entries, &ct)); for song in &ct_songs { println!( "{} - {}", diff --git a/endsong_ui/src/ui/mod.rs b/endsong_ui/src/ui/mod.rs index 7ba97a0..2ce1a82 100644 --- a/endsong_ui/src/ui/mod.rs +++ b/endsong_ui/src/ui/mod.rs @@ -712,11 +712,7 @@ fn match_plot_artist_albums( let art = read_artist(rl, entries)?; let albums_map = gather::albums_from_artist(entries, &art); - let albums = albums_map - .iter() - .sorted_unstable_by_key(|t| (std::cmp::Reverse(t.1), t.0)) - .map(|(aspect, _)| aspect) - .collect_vec(); + let albums = get_sorted_ref_list(&albums_map); let mut traces = vec![]; for (count, alb) in albums.into_iter().enumerate() { diff --git a/src/entry.rs b/src/entry.rs index 1ef89a4..8e7eb12 100644 --- a/src/entry.rs +++ b/src/entry.rs @@ -585,14 +585,4 @@ impl<'a> Find<'a> { pub fn song(&self, song_name: &str, artist_name: &str) -> Option> { find::song(self.0, song_name, artist_name) } - - /// Returns a [`Vec`] with all the songs in the given album - /// - /// # Panics - /// - /// Panics if `album` is not in the dataset - #[must_use] - pub fn songs_from_album(&self, album: &Album) -> Vec { - find::songs_from_album(self.0, album) - } } diff --git a/src/find.rs b/src/find.rs index 718074d..65f09e5 100644 --- a/src/find.rs +++ b/src/find.rs @@ -1,4 +1,22 @@ //! Module responsible for finding artists, albums and songs in the dataset +//! +//! Use functions here instead of manually creating aspects to make sure +//! they actually exist in the dataset! +//! +//! ``` +//! use endsong::prelude::*; +//! +//! // create SongEntries from a single file +//! let paths = vec![format!( +//! "{}/stuff/example_endsong/endsong_0.json", +//! std::env::current_dir().unwrap().display() +//! )]; +//! let entries = SongEntries::new(&paths).unwrap(); +//! +//! // example artist +//! let artist: Artist = entries.find().artist("sabaTON").unwrap().remove(0); +//! assert_eq!(artist, Artist::new("Sabaton")); +//! ``` use itertools::Itertools; @@ -119,20 +137,6 @@ pub fn song(entries: &[SongEntry], song_name: &str, artist_name: &str) -> Option Some(song_versions) } -/// Returns a [`Vec`] with all the songs in the given album -/// -/// # Panics -/// -/// Panics if `album` is not in the dataset -pub fn songs_from_album(entries: &[SongEntry], album: &Album) -> Vec { - entries - .iter() - .filter(|entry| album.is_entry(entry)) - .unique() - .map(Song::from) - .collect_vec() -} - #[cfg(test)] mod tests { use super::*; diff --git a/src/gather.rs b/src/gather.rs index f822b84..690afb1 100644 --- a/src/gather.rs +++ b/src/gather.rs @@ -7,9 +7,14 @@ //! Using [`&SongEntries`][crate::entry::SongEntries] is also possible for data for the whole dataset //! since it implements [`Deref`][std::ops::Deref] to the [`Vec`] it contains. //! +//! Use [`get_sorted_list`][crate::get_sorted_list] and +//! [`get_sorted_ref_list`][crate::get_sorted_ref_list] to transform the [`HashMap`]s +//! from the functions here into [`Vec`]s sorted by playcount +//! //! # Examples //! ```rust //! use endsong::prelude::*; +//! use itertools::Itertools; //! //! // create SongEntries from a single file //! let paths = vec![format!( @@ -19,7 +24,7 @@ //! let entries = SongEntries::new(&paths).unwrap(); //! //! // example artist -//! let artist = Artist::new("Sabaton"); +//! let artist: Artist = entries.find().artist("Sabaton").unwrap().remove(0); //! //! // get all albums from the artist with their plays //! let _ = gather::albums_from_artist(&entries, &artist); @@ -28,6 +33,13 @@ //! let start_date = parse_date("2020-11-14").unwrap(); //! let end_date = parse_date("now").unwrap(); //! let _ = gather::albums_from_artist(entries.between(&start_date, &end_date), &artist); +//! +//! // to get a list of albums from the artist sorted +//! // primarily by their playcount descending +//! // and then alphabetically +//! let albums_map = gather::albums_from_artist(&entries, &artist); +//! let albums: Vec<&Album> = get_sorted_ref_list(&albums_map); +//! let albums_owned: Vec = get_sorted_list(gather::albums_from_artist(&entries, &artist)); //! ``` use std::collections::HashMap; diff --git a/src/lib.rs b/src/lib.rs index f1ca5ca..5ad2600 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -31,13 +31,21 @@ pub mod prelude { pub use crate::aspect::{Album, Artist, Song}; pub use crate::aspect::{HasSongs, Music}; + pub use crate::get_sorted_list; + pub use crate::get_sorted_ref_list; pub use crate::parse_date; // time and date related pub use chrono::{DateTime, Local, NaiveDateTime, TimeDelta, TimeZone}; } +use std::collections::HashMap; + use chrono::{DateTime, Local, NaiveDateTime, TimeZone}; +use itertools::Itertools; + +use aspect::Music; + /// Converts a `YYYY-MM-DD` string to a [`DateTime`] /// in the context of the [`Local`] timezone /// @@ -102,6 +110,28 @@ pub fn parse_date(date: &str) -> Result, chrono::format::ParseEr } } +/// Makes a list of the aspect sorted by its playcount descending +/// and then the name alphabetically +#[allow(clippy::implicit_hasher)] +#[must_use] +pub fn get_sorted_list(map: HashMap) -> Vec { + map.into_iter() + .sorted_unstable_by_key(|t: &(Asp, usize)| (std::cmp::Reverse(t.1), t.0.clone())) + .map(|(aspect, _)| aspect) + .collect() +} + +/// Makes a list of references to the aspect sorted by its playcount descending +/// and then the name alphabetically +#[allow(clippy::implicit_hasher)] +#[must_use] +pub fn get_sorted_ref_list(map: &HashMap) -> Vec<&Asp> { + map.iter() + .sorted_unstable_by_key(|t: &(&Asp, &usize)| (std::cmp::Reverse(t.1), t.0)) + .map(|(aspect, _)| aspect) + .collect() +} + #[cfg(test)] mod tests { use super::*;