#[derive(Clone, Copy, PartialEq, Debug, Default)]
pub enum SortField {
#[default]
Default,
Name,
DateAdded,
Artist,
Duration,
Album,
}
impl SortField {
pub fn display_name(&self) -> &'static str {
match self {
SortField::Default => "Default",
SortField::Name => "Name",
SortField::DateAdded => "Date Added",
SortField::Artist => "Artist",
SortField::Duration => "Duration",
SortField::Album => "Album",
}
}
pub fn shortcut(&self) -> Option<char> {
match self {
SortField::Default => Some('d'),
SortField::Name => Some('n'),
SortField::DateAdded => Some('a'),
SortField::Artist => Some('r'),
SortField::Duration => Some('t'),
SortField::Album => Some('l'),
}
}
}
#[derive(Clone, Copy, PartialEq, Debug, Default)]
pub enum SortOrder {
#[default]
Ascending,
Descending,
}
impl SortOrder {
pub fn toggle(&self) -> Self {
match self {
SortOrder::Ascending => SortOrder::Descending,
SortOrder::Descending => SortOrder::Ascending,
}
}
pub fn indicator(&self) -> &'static str {
match self {
SortOrder::Ascending => "↑",
SortOrder::Descending => "↓",
}
}
}
#[derive(Clone, Copy, PartialEq, Debug)]
pub enum SortContext {
PlaylistTracks,
SavedAlbums,
SavedArtists,
#[allow(dead_code)]
RecentlyPlayed,
}
impl SortContext {
pub fn available_fields(&self) -> &'static [SortField] {
match self {
SortContext::PlaylistTracks => &[
SortField::Default,
SortField::Name,
SortField::DateAdded,
SortField::Artist,
SortField::Album,
SortField::Duration,
],
SortContext::SavedAlbums => &[
SortField::Default,
SortField::Name,
SortField::DateAdded,
SortField::Artist,
],
SortContext::SavedArtists => &[SortField::Default, SortField::Name],
SortContext::RecentlyPlayed => &[
SortField::Default,
SortField::Name,
SortField::Artist,
SortField::Album,
],
}
}
}
#[derive(Clone, Copy, PartialEq, Debug, Default)]
pub struct SortState {
pub field: SortField,
pub order: SortOrder,
}
impl SortState {
pub fn new() -> Self {
Self::default()
}
pub fn apply_field(&mut self, field: SortField) {
if self.field == field {
self.order = self.order.toggle();
} else {
self.field = field;
self.order = SortOrder::Ascending;
}
}
#[allow(dead_code)]
pub fn reset(&mut self) {
self.field = SortField::Default;
self.order = SortOrder::Ascending;
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_sort_state_apply_field() {
let mut state = SortState::new();
assert_eq!(state.field, SortField::Default);
assert_eq!(state.order, SortOrder::Ascending);
state.apply_field(SortField::Name);
assert_eq!(state.field, SortField::Name);
assert_eq!(state.order, SortOrder::Ascending);
state.apply_field(SortField::Name);
assert_eq!(state.field, SortField::Name);
assert_eq!(state.order, SortOrder::Descending);
state.apply_field(SortField::Artist);
assert_eq!(state.field, SortField::Artist);
assert_eq!(state.order, SortOrder::Ascending);
}
#[test]
fn test_sort_order_toggle() {
assert_eq!(SortOrder::Ascending.toggle(), SortOrder::Descending);
assert_eq!(SortOrder::Descending.toggle(), SortOrder::Ascending);
}
#[test]
fn test_context_available_fields() {
let fields = SortContext::PlaylistTracks.available_fields();
assert!(fields.contains(&SortField::Name));
assert!(fields.contains(&SortField::Artist));
let fields = SortContext::SavedArtists.available_fields();
assert!(fields.contains(&SortField::Name));
assert!(!fields.contains(&SortField::Artist));
}
}