use crate::error::Error;
use crate::primitive::EditorialNotes;
use crate::request::builder::MusicRequestBuilder;
use crate::request::context::ContextContainer;
use crate::request::try_resource_response;
use crate::resource::artwork::Artwork;
use crate::resource::attributes::TitleOnlyAttribute;
use crate::resource::catalog::album::Album;
use crate::resource::catalog::music_video::MusicVideo;
use crate::resource::catalog::playlist::Playlist;
use crate::resource::catalog::song::Song;
use crate::resource::catalog::station::Station;
use crate::resource::genre::Genre;
use crate::resource::relationship::Relationship;
use crate::resource::view::View;
use crate::resource::ResourceHeader;
use crate::ApiClient;
use am_api_proc_macro::{Context, ResourceProperty};
use serde::{Deserialize, Serialize};
use std::sync::Arc;
#[derive(Context, Serialize, Deserialize, Default, Debug, Clone, PartialEq, Eq, Hash)]
#[serde(rename_all = "camelCase")]
pub struct Artist {
#[context(skip)]
#[serde(flatten)]
pub header: ResourceHeader,
#[context(skip)]
#[serde(default)]
pub attributes: Option<ArtistAttributes>,
#[serde(default)]
pub relationships: ArtistRelationships,
#[serde(default)]
pub views: ArtistViews,
}
impl Artist {
pub fn get<'a>() -> ArtistGetRequestBuilder<'a> {
ArtistGetRequestBuilder::default()
}
}
#[derive(Serialize, Deserialize, Default, Debug, Clone, PartialEq, Eq, Hash)]
#[serde(rename_all = "camelCase", default)]
pub struct ArtistAttributes {
pub artwork: Option<Artwork>,
pub editorial_notes: Option<EditorialNotes>,
#[serde(rename = "genreNames")]
pub genres: Vec<String>,
pub name: String,
pub url: String,
}
#[derive(
Context, ResourceProperty, Serialize, Deserialize, Default, Debug, Clone, PartialEq, Eq, Hash,
)]
#[serde(rename_all = "camelCase", default)]
#[resource_property(ArtistRelationshipType, object = "artists", relationship)]
pub struct ArtistRelationships {
pub albums: Option<Relationship<Album>>,
pub genres: Option<Relationship<Genre>>,
#[serde(rename = "music-videos")]
pub music_videos: Option<Relationship<MusicVideo>>,
pub playlists: Option<Relationship<Playlist>>,
pub station: Option<Relationship<Station>>,
}
#[derive(
Context, ResourceProperty, Serialize, Deserialize, Default, Debug, Clone, PartialEq, Eq, Hash,
)]
#[serde(rename_all = "camelCase", default)]
#[resource_property(ArtistViewType, object = "artists", view)]
pub struct ArtistViews {
#[serde(rename = "appears-on-albums")]
pub appears_on_albums: Option<View<TitleOnlyAttribute, Album>>,
#[serde(rename = "compilation-albums")]
pub compilation_albums: Option<View<TitleOnlyAttribute, Album>>,
#[serde(rename = "featured-albums")]
pub featured_albums: Option<View<TitleOnlyAttribute, Album>>,
#[serde(rename = "featured-music-videos")]
pub featured_music_videos: Option<View<TitleOnlyAttribute, MusicVideo>>,
#[serde(rename = "featured-playlists")]
pub featured_playlists: Option<View<TitleOnlyAttribute, Playlist>>,
#[serde(rename = "full-albums")]
pub full_albums: Option<View<TitleOnlyAttribute, Album>>,
#[serde(rename = "latest-release")]
pub latest_release: Option<View<TitleOnlyAttribute, Album>>,
#[serde(rename = "live-albums")]
pub live_albums: Option<View<TitleOnlyAttribute, Album>>,
#[serde(rename = "similar-artists")]
pub similar_artists: Option<View<TitleOnlyAttribute, Artist>>,
pub singles: Option<View<TitleOnlyAttribute, Album>>,
#[serde(rename = "top-music-videos")]
pub top_music_videos: Option<View<TitleOnlyAttribute, MusicVideo>>,
#[serde(rename = "top-songs")]
pub top_songs: Option<View<TitleOnlyAttribute, Song>>,
}
pub struct ArtistRequestBuilder;
pub type ArtistGetRequestBuilder<'a> = MusicRequestBuilder<'a, ArtistRequestBuilder>;
impl<'a> ArtistGetRequestBuilder<'a> {
pub async fn one(mut self, client: &ApiClient, id: &str) -> Result<Option<Artist>, Error> {
let request_context = Arc::new(self.get_request_context_drain(client));
let response = client
.get(&format!(
"/v1/catalog/{storefront}/artists/{id}",
storefront = request_context.storefront.alpha2.to_lowercase()
))
.query(&request_context.query)
.send()
.await?;
let mut response = try_resource_response(response).await?;
response.data.set_context(request_context);
Ok(response.data.into_iter().next())
}
pub async fn many(mut self, client: &ApiClient, ids: &[&str]) -> Result<Vec<Artist>, Error> {
let mut request_context = self.get_request_context_drain(client);
request_context
.query
.push((String::from("ids"), ids.to_vec().join(",")));
let request_context = Arc::new(request_context);
let response = client
.get(&format!(
"/v1/catalog/{storefront}/artists",
storefront = request_context.storefront.alpha2.to_lowercase()
))
.query(&request_context.query)
.send()
.await?;
let mut response = try_resource_response(response).await?;
response.data.set_context(request_context);
Ok(response.data)
}
}