common/types: add type for Sort
This commit is contained in:
@@ -47,11 +47,10 @@ impl Command for Find {
|
||||
let mut sort_or_window = parts.next();
|
||||
let mut sort = None;
|
||||
if let Some("sort") = sort_or_window {
|
||||
let s = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
sort = Some(
|
||||
parts
|
||||
.next()
|
||||
.ok_or(RequestParserError::UnexpectedEOF)?
|
||||
.to_string(),
|
||||
s.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, s.to_string()))?,
|
||||
);
|
||||
sort_or_window = parts.next();
|
||||
}
|
||||
|
||||
@@ -48,11 +48,10 @@ impl Command for FindAdd {
|
||||
let mut sort_or_window_or_position = parts.next();
|
||||
let mut sort = None;
|
||||
if let Some("sort") = sort_or_window_or_position {
|
||||
let s = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
sort = Some(
|
||||
parts
|
||||
.next()
|
||||
.ok_or(RequestParserError::UnexpectedEOF)?
|
||||
.to_string(),
|
||||
s.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, s.to_string()))?,
|
||||
);
|
||||
sort_or_window_or_position = parts.next();
|
||||
}
|
||||
|
||||
@@ -47,11 +47,10 @@ impl Command for Search {
|
||||
let mut sort_or_window = parts.next();
|
||||
let mut sort = None;
|
||||
if let Some("sort") = sort_or_window {
|
||||
let s = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
sort = Some(
|
||||
parts
|
||||
.next()
|
||||
.ok_or(RequestParserError::UnexpectedEOF)?
|
||||
.to_string(),
|
||||
s.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, s.to_string()))?,
|
||||
);
|
||||
sort_or_window = parts.next();
|
||||
}
|
||||
|
||||
@@ -50,11 +50,10 @@ impl Command for SearchAdd {
|
||||
let mut sort_or_window_or_position = parts.next();
|
||||
let mut sort = None;
|
||||
if let Some("sort") = sort_or_window_or_position {
|
||||
let s = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
sort = Some(
|
||||
parts
|
||||
.next()
|
||||
.ok_or(RequestParserError::UnexpectedEOF)?
|
||||
.to_string(),
|
||||
s.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, s.to_string()))?,
|
||||
);
|
||||
sort_or_window_or_position = parts.next();
|
||||
}
|
||||
|
||||
@@ -61,11 +61,10 @@ impl Command for SearchAddPl {
|
||||
let mut sort_or_window_or_position = parts.next();
|
||||
let mut sort = None;
|
||||
if let Some("sort") = sort_or_window_or_position {
|
||||
let s = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
sort = Some(
|
||||
parts
|
||||
.next()
|
||||
.ok_or(RequestParserError::UnexpectedEOF)?
|
||||
.to_string(),
|
||||
s.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, s.to_string()))?,
|
||||
);
|
||||
sort_or_window_or_position = parts.next();
|
||||
}
|
||||
|
||||
@@ -45,11 +45,10 @@ impl Command for PlaylistFind {
|
||||
let mut sort_or_window = parts.next();
|
||||
let mut sort = None;
|
||||
if let Some("sort") = sort_or_window {
|
||||
let s = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
sort = Some(
|
||||
parts
|
||||
.next()
|
||||
.ok_or(RequestParserError::UnexpectedEOF)?
|
||||
.to_string(),
|
||||
s.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, s.to_string()))?,
|
||||
);
|
||||
sort_or_window = parts.next();
|
||||
}
|
||||
|
||||
@@ -45,11 +45,10 @@ impl Command for PlaylistSearch {
|
||||
let mut sort_or_window = parts.next();
|
||||
let mut sort = None;
|
||||
if let Some("sort") = sort_or_window {
|
||||
let s = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
sort = Some(
|
||||
parts
|
||||
.next()
|
||||
.ok_or(RequestParserError::UnexpectedEOF)?
|
||||
.to_string(),
|
||||
s.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, s.to_string()))?,
|
||||
);
|
||||
sort_or_window = parts.next();
|
||||
}
|
||||
|
||||
@@ -71,11 +71,10 @@ impl Command for StickerFind {
|
||||
let mut sort_or_window = parts.next();
|
||||
let mut sort = None;
|
||||
if let Some("sort") = sort_or_window {
|
||||
let s = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
sort = Some(
|
||||
parts
|
||||
.next()
|
||||
.ok_or(RequestParserError::UnexpectedEOF)?
|
||||
.to_string(),
|
||||
s.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, s.to_string()))?,
|
||||
);
|
||||
sort_or_window = parts.next();
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ mod one_or_range;
|
||||
mod replay_gain_mode_mode;
|
||||
mod save_mode;
|
||||
mod seek_mode;
|
||||
mod sort;
|
||||
mod subsystem;
|
||||
mod tag;
|
||||
mod time_interval;
|
||||
@@ -20,6 +21,7 @@ pub use one_or_range::OneOrRange;
|
||||
pub use replay_gain_mode_mode::ReplayGainModeMode;
|
||||
pub use save_mode::SaveMode;
|
||||
pub use seek_mode::SeekMode;
|
||||
pub use sort::Sort;
|
||||
pub use subsystem::SubSystem;
|
||||
pub use tag::Tag;
|
||||
pub use time_interval::TimeInterval;
|
||||
@@ -39,7 +41,6 @@ pub type TagName = String;
|
||||
pub type TagValue = String;
|
||||
pub type Uri = String;
|
||||
pub type Path = String;
|
||||
pub type Sort = String;
|
||||
pub type Version = String;
|
||||
pub type Feature = String;
|
||||
pub type PartitionName = String;
|
||||
|
||||
79
src/common/types/sort.rs
Normal file
79
src/common/types/sort.rs
Normal file
@@ -0,0 +1,79 @@
|
||||
// sort sorts the result by the specified tag. The sort is descending if the tag is prefixed with a minus (‘-‘). Only the first tag value will be used, if multiple of the same type exist. To sort by “Title”, “Artist”, “Album”, “AlbumArtist” or “Composer”, you should specify “TitleSort”, “ArtistSort”, “AlbumSort”, “AlbumArtistSort” or “ComposerSort” instead. These will automatically fall back to the former if “*Sort” doesn’t exist. “AlbumArtist” falls back to just “Artist”. The type “Last-Modified” can sort by file modification time, and “prio” sorts by queue priority.
|
||||
|
||||
use std::{fmt::Display, str::FromStr};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct Sort {
|
||||
pub descending: bool,
|
||||
pub key: SortKey,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub enum SortKey {
|
||||
LastModified,
|
||||
Added,
|
||||
Prio,
|
||||
Tag(super::TagName),
|
||||
}
|
||||
|
||||
impl FromStr for Sort {
|
||||
type Err = ();
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
Ok(match s.to_lowercase().as_str() {
|
||||
"last-modified" => Sort {
|
||||
descending: false,
|
||||
key: SortKey::LastModified,
|
||||
},
|
||||
"-last-modified" => Sort {
|
||||
descending: true,
|
||||
key: SortKey::LastModified,
|
||||
},
|
||||
"added" => Sort {
|
||||
descending: false,
|
||||
key: SortKey::Added,
|
||||
},
|
||||
"-added" => Sort {
|
||||
descending: true,
|
||||
key: SortKey::Added,
|
||||
},
|
||||
"prio" => Sort {
|
||||
descending: false,
|
||||
key: SortKey::Prio,
|
||||
},
|
||||
"-prio" => Sort {
|
||||
descending: true,
|
||||
key: SortKey::Prio,
|
||||
},
|
||||
other => {
|
||||
let descending = other.starts_with('-');
|
||||
let tag_str = if descending { &other[1..] } else { other };
|
||||
let tag = tag_str.parse::<super::TagName>().map_err(|_| ())?;
|
||||
Sort {
|
||||
descending,
|
||||
key: SortKey::Tag(tag),
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Sort {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Sort { descending, key } => {
|
||||
if *descending {
|
||||
write!(f, "-")?;
|
||||
}
|
||||
match key {
|
||||
SortKey::LastModified => write!(f, "last-modified"),
|
||||
SortKey::Added => write!(f, "added"),
|
||||
SortKey::Prio => write!(f, "prio"),
|
||||
SortKey::Tag(tag) => write!(f, "{}", tag),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user