Sorting improvements
This commit is contained in:
parent
39407c6551
commit
4112c7d79d
3 changed files with 75 additions and 14 deletions
src
|
@ -1,4 +1,5 @@
|
|||
use std::{
|
||||
cmp::Ordering,
|
||||
collections::{BTreeSet, HashMap},
|
||||
ffi::OsStr,
|
||||
hash::Hash,
|
||||
|
@ -9,6 +10,7 @@ use lasso2::{Rodeo, RodeoReader};
|
|||
use serde::{Deserialize, Serialize};
|
||||
use tinyvec::TinyVec;
|
||||
use trie_rs::{Trie, TrieBuilder};
|
||||
use unicase::UniCase;
|
||||
|
||||
use crate::app::index::{
|
||||
storage::{self, PathKey},
|
||||
|
@ -67,7 +69,17 @@ impl Browser {
|
|||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
files.sort();
|
||||
files.sort_by(|a, b| {
|
||||
let (a, b) = match (a, b) {
|
||||
(File::Directory(_), File::Song(_)) => return Ordering::Less,
|
||||
(File::Song(_), File::Directory(_)) => return Ordering::Greater,
|
||||
(File::Directory(a), File::Directory(b)) => (a, b),
|
||||
(File::Song(a), File::Song(b)) => (a, b),
|
||||
};
|
||||
let a = UniCase::new(a.as_os_str().to_string_lossy());
|
||||
let b = UniCase::new(b.as_os_str().to_string_lossy());
|
||||
a.cmp(&b)
|
||||
});
|
||||
|
||||
Ok(files)
|
||||
}
|
||||
|
@ -100,7 +112,11 @@ impl Browser {
|
|||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
files.sort();
|
||||
files.sort_by(|a, b| {
|
||||
let a = UniCase::new(a.as_os_str().to_string_lossy());
|
||||
let b = UniCase::new(b.as_os_str().to_string_lossy());
|
||||
a.cmp(&b)
|
||||
});
|
||||
|
||||
Ok(files)
|
||||
}
|
||||
|
@ -234,6 +250,26 @@ mod test {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn browse_entries_are_sorted() {
|
||||
let (browser, strings) = setup_test(HashSet::from([
|
||||
PathBuf::from_iter(["Ott", "Mir.mp3"]),
|
||||
PathBuf::from("Helios.mp3"),
|
||||
PathBuf::from("asura.mp3"),
|
||||
]));
|
||||
|
||||
let files = browser.browse(&strings, PathBuf::new()).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
files,
|
||||
[
|
||||
File::Directory(PathBuf::from("Ott")),
|
||||
File::Song(PathBuf::from("asura.mp3")),
|
||||
File::Song(PathBuf::from("Helios.mp3")),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_flatten_root() {
|
||||
let song_a = PathBuf::from_iter(["Music", "Electronic", "Papua New Guinea.mp3"]);
|
||||
|
@ -269,6 +305,26 @@ mod test {
|
|||
assert_eq!(files, [song_a, song_b]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn flatten_entries_are_sorted() {
|
||||
let (browser, strings) = setup_test(HashSet::from([
|
||||
PathBuf::from_iter(["Ott", "Mir.mp3"]),
|
||||
PathBuf::from("Helios.mp3"),
|
||||
PathBuf::from("asura.mp3"),
|
||||
]));
|
||||
|
||||
let files = browser.flatten(&strings, PathBuf::new()).unwrap();
|
||||
|
||||
assert_eq!(
|
||||
files,
|
||||
[
|
||||
PathBuf::from("asura.mp3"),
|
||||
PathBuf::from("Helios.mp3"),
|
||||
PathBuf::from_iter(["Ott", "Mir.mp3"]),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_flatten_directory_with_shared_prefix() {
|
||||
let directory_a = PathBuf::from_iter(["Music", "Therion", "Leviathan II"]);
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use std::{
|
||||
borrow::BorrowMut,
|
||||
cmp::Ordering,
|
||||
collections::{HashMap, HashSet},
|
||||
path::PathBuf,
|
||||
};
|
||||
|
@ -17,7 +16,7 @@ use super::storage::fetch_song;
|
|||
|
||||
#[derive(Debug, Default, PartialEq, Eq)]
|
||||
pub struct ArtistHeader {
|
||||
pub name: Option<String>,
|
||||
pub name: Option<UniCase<String>>,
|
||||
pub num_albums: u32,
|
||||
}
|
||||
|
||||
|
@ -74,12 +73,7 @@ impl Collection {
|
|||
.filter(|a| a.albums.len() > 0 || a.featured_on.len() > 1)
|
||||
.map(|a| make_artist_header(a, strings))
|
||||
.collect::<Vec<_>>();
|
||||
artists.sort_by(|a, b| match (&a.name, &b.name) {
|
||||
(Some(a), Some(b)) => UniCase::new(a).cmp(&UniCase::new(b)),
|
||||
(None, None) => Ordering::Equal,
|
||||
(None, Some(_)) => Ordering::Less,
|
||||
(Some(_), None) => Ordering::Greater,
|
||||
});
|
||||
artists.sort_by(|a, b| a.name.cmp(&b.name));
|
||||
artists
|
||||
}
|
||||
|
||||
|
@ -175,7 +169,9 @@ impl Collection {
|
|||
|
||||
fn make_artist_header(artist: &storage::Artist, strings: &RodeoReader) -> ArtistHeader {
|
||||
ArtistHeader {
|
||||
name: artist.name.map(|n| strings.resolve(&n).to_owned()),
|
||||
name: artist
|
||||
.name
|
||||
.map(|n| UniCase::new(strings.resolve(&n).to_owned())),
|
||||
num_albums: artist.albums.len() as u32 + artist.featured_on.len() as u32,
|
||||
}
|
||||
}
|
||||
|
@ -326,7 +322,13 @@ mod test {
|
|||
.map(|a| a.name.unwrap())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
assert_eq!(artists, vec!["FSOL".to_owned(), "Stratovarius".to_owned()]);
|
||||
assert_eq!(
|
||||
artists,
|
||||
vec![
|
||||
UniCase::new("FSOL".to_owned()),
|
||||
UniCase::new("Stratovarius".to_owned())
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -354,7 +356,10 @@ mod test {
|
|||
|
||||
assert_eq!(
|
||||
artists,
|
||||
vec!["hammerfall".to_owned(), "Heavenly".to_owned()]
|
||||
vec![
|
||||
UniCase::new("hammerfall".to_owned()),
|
||||
UniCase::new("Heavenly".to_owned())
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -315,7 +315,7 @@ pub struct ArtistHeader {
|
|||
impl From<index::ArtistHeader> for ArtistHeader {
|
||||
fn from(a: index::ArtistHeader) -> Self {
|
||||
Self {
|
||||
name: a.name,
|
||||
name: a.name.map(|s| s.into_inner()),
|
||||
num_albums: a.num_albums,
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue