use crate::error::Error;
use crate::primitive::{ContentRating, EditorialNotes, PlayParameters};
use crate::request::builder::MusicRequestBuilder;
use crate::request::context::ContextContainer;
use crate::request::paginated::paginate;
use crate::request::try_resource_response;
use crate::resource::artwork::Artwork;
use crate::resource::catalog::curator::AppleCurator;
use crate::resource::relationship::Relationship;
use crate::resource::ResourceHeader;
use crate::ApiClient;
use am_api_proc_macro::{Context, ResourceProperty};
use futures::Stream;
use serde::{Deserialize, Serialize};
use std::sync::Arc;
#[derive(Context, Serialize, Deserialize, Default, Debug, Clone, PartialEq, Eq, Hash)]
#[serde(rename_all = "camelCase")]
pub struct Station {
#[context(skip)]
#[serde(flatten)]
pub header: ResourceHeader,
#[context(skip)]
#[serde(default)]
pub attributes: Option<StationAttributes>,
#[serde(default)]
pub relationships: StationRelationships,
}
impl Station {
pub fn get<'a>() -> StationGetRequestBuilder<'a> {
StationGetRequestBuilder::default()
}
}
#[derive(Serialize, Deserialize, Default, Debug, Clone, PartialEq, Eq, Hash)]
#[serde(rename_all = "camelCase", default)]
pub struct StationAttributes {
pub artwork: Artwork,
pub duration_in_millis: Option<u32>,
pub editorial_notes: Option<EditorialNotes>,
pub episode_number: Option<String>,
pub content_rating: Option<ContentRating>,
pub is_live: bool,
pub media_kind: MediaKind,
pub name: String,
pub play_params: Option<PlayParameters>,
pub station_provider_name: Option<String>,
pub url: String,
}
#[derive(
Context, ResourceProperty, Serialize, Deserialize, Default, Debug, Clone, PartialEq, Eq, Hash,
)]
#[serde(rename_all = "camelCase", default)]
#[resource_property(StationRelationshipType, object = "stations", relationship)]
pub struct StationRelationships {
#[serde(rename = "radio-show")]
pub radio_show: Option<Relationship<AppleCurator>>,
}
pub struct StationRequestBuilder;
pub type StationGetRequestBuilder<'a> = MusicRequestBuilder<'a, StationRequestBuilder>;
impl<'a> StationGetRequestBuilder<'a> {
pub async fn one(mut self, client: &ApiClient, id: &str) -> Result<Option<Station>, Error> {
let request_context = Arc::new(self.get_request_context_drain(client));
let response = client
.get(&format!(
"/v1/catalog/{storefront}/stations/{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<Station>, 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}/stations",
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)
}
pub async fn live(mut self, client: &ApiClient) -> Result<Vec<Station>, Error> {
let mut request_context = self.get_request_context_drain(client);
request_context.query.push((
String::from("filter[featured]"),
String::from("apple-music-live-radio"),
));
let request_context = Arc::new(request_context);
let response = client
.get(&format!(
"/v1/catalog/{storefront}/stations",
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)
}
pub async fn personal(mut self, client: &ApiClient) -> Result<Option<Station>, Error> {
let mut request_context = self.get_request_context_drain(client);
request_context
.query
.push((String::from("filter[identity]"), String::from("personal")));
let request_context = Arc::new(request_context);
let response = client
.get(&format!(
"/v1/catalog/{storefront}/stations",
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())
}
}
#[derive(Serialize, Deserialize, Default, Debug, Clone, PartialEq, Eq, Hash)]
pub enum MediaKind {
#[serde(rename = "audio")]
#[default]
Audio,
#[serde(rename = "video")]
Video,
}
#[derive(Context, Serialize, Deserialize, Default, Debug, Clone, PartialEq, Eq, Hash)]
#[serde(rename_all = "camelCase")]
pub struct StationGenre {
#[context(skip)]
#[serde(flatten)]
pub header: ResourceHeader,
#[context(skip)]
#[serde(default)]
pub attributes: Option<StationGenreAttributes>,
#[serde(default)]
pub relationships: StationGenreRelationships,
}
impl StationGenre {
pub fn get<'a>() -> StationGenreGetRequestBuilder<'a> {
StationGenreGetRequestBuilder::default()
}
}
#[derive(Serialize, Deserialize, Default, Debug, Clone, PartialEq, Eq, Hash)]
#[serde(rename_all = "camelCase", default)]
pub struct StationGenreAttributes {
pub name: String,
}
#[derive(
Context, ResourceProperty, Serialize, Deserialize, Default, Debug, Clone, PartialEq, Eq, Hash,
)]
#[serde(rename_all = "camelCase", default)]
#[resource_property(StationGenreRelationshipType, object = "station-genres", relationship)]
pub struct StationGenreRelationships {
pub stations: Option<Relationship<Station>>,
}
pub struct StationGenreRequestBuilder;
pub type StationGenreGetRequestBuilder<'a> = MusicRequestBuilder<'a, StationGenreRequestBuilder>;
impl<'a> StationGenreGetRequestBuilder<'a> {
pub async fn one(
mut self,
client: &ApiClient,
id: &str,
) -> Result<Option<StationGenre>, Error> {
let request_context = Arc::new(self.get_request_context_drain(client));
let response = client
.get(&format!(
"/v1/catalog/{storefront}/station-genres/{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<StationGenre>, 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}/station-genres",
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)
}
pub fn all(
mut self,
client: &ApiClient,
limit: usize,
offset: usize,
) -> impl Stream<Item = Result<StationGenre, Error>> {
let mut request_context = self.get_request_context_drain(client);
request_context
.query
.push((String::from("limit"), limit.to_string()));
paginate(
client.clone(),
format!(
"/v1/catalog/{storefront}/station-genres",
storefront = request_context.storefront.alpha2.to_lowercase()
),
request_context,
offset,
)
}
}