use crate::error::Error;
use crate::request::builder::MusicRequestBuilder;
use crate::request::context::ContextContainer;
use crate::resource::library::album::LibraryAlbum;
use crate::resource::library::artist::LibraryArtist;
use crate::resource::library::music_video::LibraryMusicVideo;
use crate::resource::library::playlist::LibraryPlaylist;
use crate::resource::library::song::LibrarySong;
use crate::resource::relationship::Relationship;
use crate::resource::ErrorResponse;
use crate::ApiClient;
use am_api_proc_macro::Context;
use serde::{Deserialize, Serialize};
use std::fmt::{Display, Formatter};
use std::sync::Arc;
pub struct LibrarySearch;
pub struct LibrarySearchRequestBuilderMarker;
pub type LibrarySearchRequestBuilder<'a> =
MusicRequestBuilder<'a, LibrarySearchRequestBuilderMarker>;
impl<'a> LibrarySearchRequestBuilder<'a> {
pub async fn search(
mut self,
client: &ApiClient,
types: &[LibrarySearchType],
term: &str,
) -> Result<LibrarySearchResults, Error> {
let mut request_context = self.get_request_context_drain(client);
request_context.query.push((
String::from("types"),
types
.iter()
.map(|e| e.to_string())
.collect::<Vec<_>>()
.join(","),
));
request_context
.query
.push((String::from("term"), term.to_string().replace(' ', "+")));
let request_context = Arc::new(request_context);
let response = client
.get("/v1/me/library/search")
.query(&request_context.query)
.send()
.await?;
if !response.status().is_success() {
let error_response: ErrorResponse = response.json().await?;
return Err(Error::MusicError(error_response));
}
let mut response = response.json::<LibrarySearchResponse>().await?;
response.results.set_context(request_context);
Ok(response.results)
}
}
#[derive(Context, Serialize, Deserialize, Default, Debug, Clone, PartialEq, Eq, Hash)]
#[serde(default)]
pub struct LibrarySearchResults {
#[serde(rename = "library-albums")]
pub library_albums: Relationship<LibraryAlbum>,
#[serde(rename = "library-artists")]
pub library_artists: Relationship<LibraryArtist>,
#[serde(rename = "library-music-videos")]
pub library_music_videos: Relationship<LibraryMusicVideo>,
#[serde(rename = "library-playlists")]
pub library_playlists: Relationship<LibraryPlaylist>,
#[serde(rename = "library-songs")]
pub library_songs: Relationship<LibrarySong>,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub enum LibrarySearchType {
LibraryAlbums,
LibraryArtists,
LibraryMusicVideos,
LibraryPlaylists,
LibrarySongs,
}
impl Display for LibrarySearchType {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let s = match self {
LibrarySearchType::LibraryAlbums => "library-albums",
LibrarySearchType::LibraryArtists => "library-artists",
LibrarySearchType::LibraryMusicVideos => "library-music-videos",
LibrarySearchType::LibraryPlaylists => "library-playlists",
LibrarySearchType::LibrarySongs => "library-songs",
};
write!(f, "{}", s)
}
}
#[derive(Serialize, Deserialize)]
struct LibrarySearchResponse {
results: LibrarySearchResults,
}