use crate::error::Error;
use crate::primitive::{AudioVariant, ContentRating, EditorialNotes, PlayParameters};
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::artist::Artist;
use crate::resource::catalog::music_video::MusicVideo;
use crate::resource::catalog::playlist::Playlist;
use crate::resource::catalog::record_label::RecordLabel;
use crate::resource::genre::Genre;
use crate::resource::library::album::LibraryAlbum;
use crate::resource::relationship::Relationship;
use crate::resource::view::View;
use crate::resource::{Resource, ResourceHeader};
use crate::utils::year_or_date::YearOrDate;
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 Album {
#[context(skip)]
#[serde(flatten)]
pub header: ResourceHeader,
#[context(skip)]
#[serde(default)]
pub attributes: Option<AlbumAttributes>,
#[serde(default)]
pub relationships: AlbumRelationships,
#[serde(default)]
pub views: AlbumViews,
}
impl Album {
pub fn get<'a>() -> AlbumGetRequestBuilder<'a> {
AlbumGetRequestBuilder::default()
}
}
#[derive(ResourceProperty, Serialize, Deserialize, Default, Debug, Clone, PartialEq, Eq, Hash)]
#[serde(rename_all = "camelCase", default)]
#[resource_property(AlbumAttributesExtension, object = "albums", extension, whitelist)]
pub struct AlbumAttributes {
pub artist_name: String,
#[resource_property(whitelist, name = "artistUrl")]
pub artist_url: Option<String>,
pub artwork: Artwork,
pub audio_variants: Option<Vec<AudioVariant>>,
pub content_rating: Option<ContentRating>,
pub copyright: String,
pub editorial_notes: Option<EditorialNotes>,
pub genre_names: Vec<String>,
pub is_compilation: bool,
pub is_complete: bool,
pub is_mastered_for_itunes: bool,
pub is_single: bool,
pub name: String,
pub play_params: Option<PlayParameters>,
pub record_label: Option<String>,
pub release_date: Option<YearOrDate>,
pub track_count: u32,
pub upc: Option<String>,
pub url: String,
}
#[derive(
Context, ResourceProperty, Serialize, Deserialize, Default, Debug, Clone, PartialEq, Eq, Hash,
)]
#[serde(rename_all = "camelCase", default)]
#[resource_property(AlbumRelationshipType, object = "albums", relationship)]
pub struct AlbumRelationships {
pub artists: Relationship<Artist>,
pub genres: Relationship<Genre>,
pub tracks: Relationship<Resource>,
pub library: Relationship<LibraryAlbum>,
#[serde(rename = "record-labels")]
pub record_labels: Relationship<RecordLabel>,
}
#[derive(
Context, ResourceProperty, Serialize, Deserialize, Default, Debug, Clone, PartialEq, Eq, Hash,
)]
#[serde(rename_all = "camelCase", default)]
#[resource_property(AlbumViewType, object = "albums", view)]
pub struct AlbumViews {
#[serde(rename = "appears-on")]
pub appears_on: Option<View<TitleOnlyAttribute, Playlist>>,
#[serde(rename = "other-versions")]
pub other_versions: Option<View<TitleOnlyAttribute, Album>>,
#[serde(rename = "related-albums")]
pub related_albums: Option<View<TitleOnlyAttribute, Album>>,
#[serde(rename = "related-videos")]
pub related_videos: Option<View<TitleOnlyAttribute, MusicVideo>>,
}
pub struct AlbumRequestBuilder;
pub type AlbumGetRequestBuilder<'a> = MusicRequestBuilder<'a, AlbumRequestBuilder>;
impl<'a> AlbumGetRequestBuilder<'a> {
pub async fn one(mut self, client: &ApiClient, id: &str) -> Result<Option<Album>, Error> {
let request_context = Arc::new(self.get_request_context_drain(client));
let response = client
.get(&format!(
"/v1/catalog/{storefront}/albums/{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],
upc: bool,
) -> Result<Vec<Album>, Error> {
let mut request_context = self.get_request_context_drain(client);
let ids = ids.to_vec().join(",");
let id_query = match upc {
true => "filter[upc]",
false => "ids",
};
request_context.query.push((id_query.to_string(), ids));
let request_context = Arc::new(request_context);
let response = client
.get(&format!(
"/v1/catalog/{storefront}/albums",
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)
}
}