1use crate::mc::artist::AnyArtist;
2use crate::mc::label::Brand;
3use crate::mc::util::{CacheDetails, Link};
4use iso8601_timestamp::Timestamp;
5use serde::{Deserialize, Serialize};
6use std::fmt::Display;
7use std::ops::Deref;
8use uuid::Uuid;
9
10#[derive(Clone, Copy, Debug, PartialEq, Deserialize, Serialize)]
12pub struct ReleaseID(pub Uuid);
13
14impl Deref for ReleaseID {
15 type Target = Uuid;
16
17 fn deref(&self) -> &Self::Target {
18 &self.0
19 }
20}
21
22impl Display for ReleaseID {
23 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
24 write!(f, "{}", self.0)
25 }
26}
27
28#[derive(Clone, Copy, Debug, PartialEq, Deserialize, Serialize)]
30pub struct TrackID(pub Uuid);
31
32impl Deref for TrackID {
33 type Target = Uuid;
34
35 fn deref(&self) -> &Self::Target {
36 &self.0
37 }
38}
39
40impl Display for TrackID {
41 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42 write!(f, "{}", self.0)
43 }
44}
45
46#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
48pub struct CatalogID(pub String);
49
50impl Deref for CatalogID {
51 type Target = String;
52
53 fn deref(&self) -> &Self::Target {
54 &self.0
55 }
56}
57
58impl Display for CatalogID {
59 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
60 write!(f, "{}", self.0)
61 }
62}
63
64#[derive(Clone, Debug, Deserialize, Serialize)]
66#[serde(untagged)]
67pub enum AnyRelease {
68 Release(Release),
69 Track(Track),
70}
71
72impl AnyRelease {
73 pub fn get_type(&self) -> &str {
75 match self {
76 AnyRelease::Release(a) => &a.kind,
77 AnyRelease::Track(_) => "Track",
78 }
79 }
80
81 pub fn get_title(&self) -> &str {
83 match self {
84 AnyRelease::Release(a) => &a.title,
85 AnyRelease::Track(t) => &t.title,
86 }
87 }
88
89 pub fn get_artists(&self) -> &str {
91 match self {
92 AnyRelease::Release(a) => &a.artists_title,
93 AnyRelease::Track(t) => &t.artists_title,
94 }
95 }
96
97 pub fn get_date(&self) -> &Timestamp {
99 match self {
100 AnyRelease::Release(a) => &a.release_date,
101 AnyRelease::Track(t) => &t.release.release_date,
102 }
103 }
104
105 pub fn get_release_id(&self) -> &ReleaseID {
107 match self {
108 AnyRelease::Release(release) => &release.id,
109 AnyRelease::Track(track) => &track.release.id,
110 }
111 }
112}
113
114#[derive(Clone, Debug, Deserialize, Serialize)]
116#[serde(rename_all = "PascalCase")]
117pub struct Release {
118 pub album_notes: Option<String>,
119 pub artists: Option<Vec<AnyArtist>>,
120 pub artists_title: String,
121 pub brand_id: Option<Brand>,
122 pub brand_title: Option<String>,
123 #[serde(flatten)]
124 pub cache_details: Option<CacheDetails>,
125 pub catalog_id: CatalogID,
126 pub copyright_p_line: Option<String>,
127 pub cover_file_id: Option<String>,
128 pub description: String,
129 pub downloadable: Option<bool>,
130 pub featured_artists_title: String,
131 #[serde(alias = "GRid")]
132 pub grid: Option<String>,
133 pub genre_primary: Option<String>,
134 pub genre_secondary: Option<String>,
135 pub id: ReleaseID,
136 pub in_early_access: Option<bool>,
137 pub links: Option<Vec<Link>>,
138 pub prerelease_date: Option<Timestamp>,
139 pub presave_date: Option<Timestamp>,
140 pub release_date: Timestamp,
141 pub release_date_timezone: String,
142 pub spotify_id: Option<String>,
143 pub streamable: Option<bool>,
144 pub tags: Option<Vec<String>>,
145 pub title: String,
146 pub tracks: Option<Vec<Track>>,
147 #[serde(alias = "Type")]
148 pub kind: String,
149 #[serde(alias = "UPC")]
150 pub upc: Option<String>,
151 pub version: String,
152 #[serde(alias = "YouTubeUrl")]
153 pub youtube_url: Option<String>,
154}
155
156#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
158#[serde(rename_all = "PascalCase")]
159pub struct ReleaseSummary {
160 pub artists_title: String,
161 pub catalog_id: String,
162 pub copyright_p_line: Option<String>,
163 pub description: String,
164 pub id: ReleaseID,
165 pub release_date: Timestamp,
166 pub release_date_timezone: String,
167 pub tags: Option<Vec<String>>,
168 pub title: String,
169 #[serde(alias = "Type")]
170 pub kind: String,
171 #[serde(alias = "UPC")]
172 pub upc: Option<String>,
173 pub version: String,
174}
175
176#[derive(Clone, Debug, Deserialize, Serialize)]
178#[serde(rename_all = "PascalCase")]
179pub struct Track {
180 pub artists: Option<Vec<AnyArtist>>,
181 pub artists_title: String,
182 #[serde(alias = "BPM")]
183 pub bpm: usize,
184 pub brand: String,
185 pub brand_id: usize,
186 pub creator_friendly: bool,
187 pub debut_date: Option<Timestamp>,
188 pub downloadable: bool,
189 pub duration: usize,
190 pub explicit: bool,
191 pub genre_primary: String,
192 pub genre_secondary: String,
193 #[serde(alias = "ISRC")]
194 pub isrc: String,
195 pub id: TrackID,
196 pub in_early_access: bool,
197 pub lock_status: String,
198 pub public: bool,
199 pub playlist_sort: Option<u32>,
200 pub release: ReleaseSummary,
201 pub streamable: bool,
202 pub tags: Option<Vec<String>>,
203 pub title: String,
204 pub track_number: usize,
205 pub version: String,
206}