#[cfg(feature = "catchall")]
use std::collections::HashMap;
use serde::{Deserialize, Serialize};
#[cfg(feature = "catchall")]
use serde_json::Value;
use super::{
ArtistCoreNoMetadata, Referent, SongMetadata, Text, UserCore,
UserInteractionMetadata,
};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
pub struct SongResponse {
pub song: Song,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
pub struct Song {
pub apple_music_id: Option<String>,
pub apple_music_player_url: String,
pub current_user_metadata: SongMetadata,
pub description: Text,
pub embed_content: String,
pub featured_video: bool,
pub language: Option<String>,
pub lyrics_placeholder_reason: Option<String>,
pub recording_location: Option<String>,
pub release_date: Option<String>,
pub album: Option<Album>,
pub custom_performances: Vec<Performance>,
pub description_annotation: Referent,
pub lyrics_marked_complete_by: Option<UserCore<UserInteractionMetadata>>,
pub lyrics_marked_staff_approved_by: Option<UserCore<UserInteractionMetadata>>,
pub media: Vec<Media>,
pub producer_artists: Vec<ArtistCoreNoMetadata>,
pub song_relationships: Vec<SongRelationship>,
pub translation_songs: Vec<TranslationSong>,
pub verified_annotations_by: Vec<UserCore<UserInteractionMetadata>>,
pub verified_contributors: Vec<Contribution>,
pub verified_lyrics_by: Vec<UserCore<UserInteractionMetadata>>,
pub writer_artists: Vec<ArtistCoreNoMetadata>,
#[serde(flatten)]
pub core: SongCore<SongStats>,
#[cfg(feature = "catchall")]
#[serde(flatten)]
pub extra: HashMap<String, Value>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type")]
#[serde(rename_all = "lowercase")]
pub enum Media {
Audio(Audio),
Video(Video),
}
impl Default for Media {
fn default() -> Self {
Media::Audio(Audio::default())
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
pub struct Audio {
#[serde(skip_serializing_if = "Option::is_none")]
pub attribution: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub native_uri: Option<String>,
pub provider: String,
pub url: String,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
pub struct Video {
pub provider: String,
pub url: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub start: Option<u32>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
pub struct SongRelationship {
#[serde(rename = "type")]
rel_type: RelationshipType,
pub relationship_type: RelationshipType,
pub url: Option<String>,
pub songs: Vec<SongCoreWithRDC<SongCoreStats>>,
}
#[derive(Debug, Clone, Copy, PartialEq, Deserialize, Serialize, Default)]
#[serde(rename_all = "snake_case")]
pub enum RelationshipType {
Samples,
SampledIn,
Interpolates,
InterpolatedBy,
CoverOf,
CoveredBy,
RemixOf,
RemixedBy,
LiveVersionOf,
PerformedLiveAs,
TranslationOf,
Translations,
#[default]
Unknown,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
pub struct Contribution {
pub contributions: Vec<String>,
pub artist: ArtistCoreNoMetadata,
pub user: Option<UserCore<UserInteractionMetadata>>,
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Default)]
pub struct SongStats {
pub accepted_annotations: u32,
pub contributors: u32,
pub iq_earners: u32,
pub transcribers: u32,
pub verified_annotations: u32,
#[serde(flatten)]
pub core: SongCoreStats,
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Default)]
pub struct SongCoreStats {
#[serde(skip_serializing_if = "Option::is_none")]
pub concurrents: Option<u16>,
#[serde(rename = "pageviews", skip_serializing_if = "Option::is_none")]
pub page_views: Option<u32>,
pub unreviewed_annotations: u32,
pub hot: bool,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
pub struct Performance {
pub label: String,
pub artists: Vec<ArtistCoreNoMetadata>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
pub struct Album {
pub api_path: String,
pub cover_art_url: String,
pub full_title: String,
pub id: u32,
pub name: String,
pub release_date_for_display: Option<String>,
pub url: String,
pub artist: ArtistCoreNoMetadata,
#[cfg(feature = "catchall")]
#[serde(flatten)]
pub extra: HashMap<String, Value>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
pub struct SongCoreWithRDC<S> {
pub release_date_components: Option<DateComponents>,
#[serde(flatten)]
pub core: SongCore<S>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
pub struct SongCore<S> {
pub annotation_count: u32,
pub artist_names: String,
pub full_title: String,
pub header_image_thumbnail_url: String,
pub header_image_url: String,
pub lyrics_owner_id: u32,
pub pyongs_count: Option<u32>,
pub relationships_index_url: String,
pub release_date_for_display: Option<String>,
pub release_date_with_abbreviated_month_for_display: Option<String>,
pub song_art_image_thumbnail_url: String,
pub song_art_image_url: String,
pub stats: S,
pub title_with_featured: String,
pub featured_artists: Vec<ArtistCoreNoMetadata>,
pub primary_artist: ArtistCoreNoMetadata,
#[serde(flatten)]
pub essential: SongEssential,
#[cfg(feature = "catchall")]
#[serde(flatten)]
pub extra: HashMap<String, Value>,
}
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, Default)]
pub struct DateComponents {
pub year: u16,
pub month: Option<u8>,
pub day: Option<u8>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
pub struct TranslationSong {
pub language: Option<String>,
#[serde(flatten)]
pub essential: SongEssential,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
pub struct SongEssential {
pub api_path: String,
pub id: u32,
pub lyrics_state: String,
pub path: String,
pub title: String,
pub url: String,
}