use crate::Client;
use crate::data::{AlbumId3, ArtistId3, Child, NowPlayingEntry};
use crate::error::Error;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AlbumListType {
Random,
Newest,
Highest,
Frequent,
Recent,
AlphabeticalByName,
AlphabeticalByArtist,
Starred,
ByYear,
ByGenre,
}
impl AlbumListType {
fn as_str(self) -> &'static str {
match self {
Self::Random => "random",
Self::Newest => "newest",
Self::Highest => "highest",
Self::Frequent => "frequent",
Self::Recent => "recent",
Self::AlphabeticalByName => "alphabeticalByName",
Self::AlphabeticalByArtist => "alphabeticalByArtist",
Self::Starred => "starred",
Self::ByYear => "byYear",
Self::ByGenre => "byGenre",
}
}
}
impl Client {
#[allow(clippy::too_many_arguments)]
pub async fn get_album_list(
&self,
list_type: AlbumListType,
size: Option<i32>,
offset: Option<i32>,
from_year: Option<i32>,
to_year: Option<i32>,
genre: Option<&str>,
music_folder_id: Option<&str>,
) -> Result<Vec<Child>, Error> {
let mut params = vec![("type", list_type.as_str().to_string())];
if let Some(s) = size {
params.push(("size", s.to_string()));
}
if let Some(o) = offset {
params.push(("offset", o.to_string()));
}
if let Some(y) = from_year {
params.push(("fromYear", y.to_string()));
}
if let Some(y) = to_year {
params.push(("toYear", y.to_string()));
}
if let Some(g) = genre {
params.push(("genre", g.to_string()));
}
if let Some(id) = music_folder_id {
params.push(("musicFolderId", id.to_string()));
}
let param_refs: Vec<(&str, &str)> = params.iter().map(|(k, v)| (*k, v.as_str())).collect();
let data = self.get_response("getAlbumList", ¶m_refs).await?;
let albums = data
.get("albumList")
.and_then(|v| v.get("album"))
.cloned()
.unwrap_or_else(|| serde_json::Value::Array(vec![]));
Ok(serde_json::from_value(albums)?)
}
#[allow(clippy::too_many_arguments)]
pub async fn get_album_list2(
&self,
list_type: AlbumListType,
size: Option<i32>,
offset: Option<i32>,
from_year: Option<i32>,
to_year: Option<i32>,
genre: Option<&str>,
music_folder_id: Option<&str>,
) -> Result<Vec<AlbumId3>, Error> {
let mut params = vec![("type", list_type.as_str().to_string())];
if let Some(s) = size {
params.push(("size", s.to_string()));
}
if let Some(o) = offset {
params.push(("offset", o.to_string()));
}
if let Some(y) = from_year {
params.push(("fromYear", y.to_string()));
}
if let Some(y) = to_year {
params.push(("toYear", y.to_string()));
}
if let Some(g) = genre {
params.push(("genre", g.to_string()));
}
if let Some(id) = music_folder_id {
params.push(("musicFolderId", id.to_string()));
}
let param_refs: Vec<(&str, &str)> = params.iter().map(|(k, v)| (*k, v.as_str())).collect();
let data = self.get_response("getAlbumList2", ¶m_refs).await?;
let albums = data
.get("albumList2")
.and_then(|v| v.get("album"))
.cloned()
.unwrap_or_else(|| serde_json::Value::Array(vec![]));
Ok(serde_json::from_value(albums)?)
}
pub async fn get_random_songs(
&self,
size: Option<i32>,
genre: Option<&str>,
from_year: Option<i32>,
to_year: Option<i32>,
music_folder_id: Option<&str>,
) -> Result<Vec<Child>, Error> {
let mut params = Vec::new();
if let Some(s) = size {
params.push(("size", s.to_string()));
}
if let Some(g) = genre {
params.push(("genre", g.to_string()));
}
if let Some(y) = from_year {
params.push(("fromYear", y.to_string()));
}
if let Some(y) = to_year {
params.push(("toYear", y.to_string()));
}
if let Some(id) = music_folder_id {
params.push(("musicFolderId", id.to_string()));
}
let param_refs: Vec<(&str, &str)> = params.iter().map(|(k, v)| (*k, v.as_str())).collect();
let data = self.get_response("getRandomSongs", ¶m_refs).await?;
let songs = data
.get("randomSongs")
.and_then(|v| v.get("song"))
.cloned()
.unwrap_or_else(|| serde_json::Value::Array(vec![]));
Ok(serde_json::from_value(songs)?)
}
pub async fn get_songs_by_genre(
&self,
genre: &str,
count: Option<i32>,
offset: Option<i32>,
music_folder_id: Option<&str>,
) -> Result<Vec<Child>, Error> {
let mut params = vec![("genre", genre.to_string())];
if let Some(c) = count {
params.push(("count", c.to_string()));
}
if let Some(o) = offset {
params.push(("offset", o.to_string()));
}
if let Some(id) = music_folder_id {
params.push(("musicFolderId", id.to_string()));
}
let param_refs: Vec<(&str, &str)> = params.iter().map(|(k, v)| (*k, v.as_str())).collect();
let data = self.get_response("getSongsByGenre", ¶m_refs).await?;
let songs = data
.get("songsByGenre")
.and_then(|v| v.get("song"))
.cloned()
.unwrap_or_else(|| serde_json::Value::Array(vec![]));
Ok(serde_json::from_value(songs)?)
}
pub async fn get_now_playing(&self) -> Result<Vec<NowPlayingEntry>, Error> {
let data = self.get_response("getNowPlaying", &[]).await?;
let entries = data
.get("nowPlaying")
.and_then(|v| v.get("entry"))
.cloned()
.unwrap_or_else(|| serde_json::Value::Array(vec![]));
Ok(serde_json::from_value(entries)?)
}
pub async fn get_starred(
&self,
music_folder_id: Option<&str>,
) -> Result<StarredContent, Error> {
let mut params = Vec::new();
if let Some(id) = music_folder_id {
params.push(("musicFolderId", id));
}
let data = self.get_response("getStarred", ¶ms).await?;
let starred = data
.get("starred")
.ok_or_else(|| Error::Parse("Missing 'starred' in response".into()))?;
Ok(serde_json::from_value(starred.clone())?)
}
pub async fn get_starred2(
&self,
music_folder_id: Option<&str>,
) -> Result<Starred2Content, Error> {
let mut params = Vec::new();
if let Some(id) = music_folder_id {
params.push(("musicFolderId", id));
}
let data = self.get_response("getStarred2", ¶ms).await?;
let starred = data
.get("starred2")
.ok_or_else(|| Error::Parse("Missing 'starred2' in response".into()))?;
Ok(serde_json::from_value(starred.clone())?)
}
}
#[derive(Debug, Clone, PartialEq, Default, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct StarredContent {
#[serde(default)]
pub artist: Vec<crate::data::Artist>,
#[serde(default)]
pub album: Vec<Child>,
#[serde(default)]
pub song: Vec<Child>,
}
#[derive(Debug, Clone, PartialEq, Default, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Starred2Content {
#[serde(default)]
pub artist: Vec<ArtistId3>,
#[serde(default)]
pub album: Vec<AlbumId3>,
#[serde(default)]
pub song: Vec<Child>,
}