bombay/mc/
release.rs

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/// NewType for release identifier, wraps a UUID and adds type safety.
11#[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/// NewType for track identifier, wraps a UUID and adds type safety.
29#[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/// NewType for release catalog identifier, wraps a UUID and adds type safety.
47#[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/// Enumerated type to capture the possible release types.
65#[derive(Clone, Debug, Deserialize, Serialize)]
66#[serde(untagged)]
67pub enum AnyRelease {
68    Release(Release),
69    Track(Track),
70}
71
72impl AnyRelease {
73    /// Get any release's type.
74    pub fn get_type(&self) -> &str {
75        match self {
76            AnyRelease::Release(a) => &a.kind,
77            AnyRelease::Track(_) => "Track",
78        }
79    }
80
81    /// Get any release's title.
82    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    /// Get any release's artists.
90    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    /// Get any release's release date.
98    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    /// Get any release's release identifier.
106    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/// Most detailed release object returned by the MC API.
115#[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/// Summarized release details.
157#[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/// Detailed release track information.
177#[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}