genius_rust/
song.rs

1use serde::{Serialize, Deserialize};
2
3use crate::album::Album;
4use crate::annotation::Referent;
5use crate::user::{User, UserMetadata};
6use crate::{Body, Date};
7
8#[derive(Serialize, Deserialize, Debug)]
9pub struct Song {
10    /// Number of annotations on this song.
11    pub annotation_count: u32,
12    /// Path of the API.
13    pub api_path: String,
14    /// Id of the song in apple music.
15    /// > Only in `get_song`
16    #[serde(skip_serializing_if = "Option::is_none")]
17    pub apple_music_id: Option<String>,
18    /// URL of the song in apple music.
19    /// > Only in `get_song`
20    #[serde(skip_serializing_if = "Option::is_none")]
21    pub apple_music_player_url: Option<String>,
22    /// Number of comments on this song.
23    /// > Only in `get_song` with `user-core` level token
24    #[serde(skip_serializing_if = "Option::is_none")]
25    pub comment_count: Option<u32>,
26    /// Custom header image.
27    /// > Only in `get_song` with `user-core` level token
28    #[serde(skip_serializing_if = "Option::is_none")]
29    pub custom_header_image_url: Option<String>,
30    /// Custom song art image.
31    /// > Only in `get_song` with `user-core` level token
32    #[serde(skip_serializing_if = "Option::is_none")]
33    pub custom_song_art_image_url: Option<String>,
34    /// Description of the music.
35    /// > Only in `get_song`
36    #[serde(skip_serializing_if = "Option::is_none")]
37    pub description: Option<Body>,
38    /// Preview of the description.
39    /// > Only in `get_song` with `user-core` level token
40    #[serde(skip_serializing_if = "Option::is_none")]
41    pub description_preview: Option<String>,
42    /// HTML to embed the content in a web page.
43    /// > Only in `get_song`
44    #[serde(skip_serializing_if = "Option::is_none")]
45    pub embed_content: Option<String>,
46    /// Facebook share message without url.
47    /// > Only in `get_song` with `user-core` level token
48    #[serde(skip_serializing_if = "Option::is_none")]
49    pub facebook_share_message_without_url: Option<String>,
50    /// If has a video linked with this song.
51    /// > Only in `get_song`
52    #[serde(skip_serializing_if = "Option::is_none")]
53    pub featured_video: Option<bool>,
54    /// Full song title is: "`name` by `author`".
55    pub full_title: String,
56    /// If has instagram reels annotations.
57    /// > Only in `get_song` with `user-core` level token
58    #[serde(skip_serializing_if = "Option::is_none")]
59    pub has_instagram_reel_annotations: Option<bool>,
60    /// Header image with a smaller size.
61    pub header_image_thumbnail_url: String,
62    /// Header image.
63    pub header_image_url: String,
64    /// If this song is hidden?
65    /// > Only in `get_song` with `user-core` level token
66    #[serde(skip_serializing_if = "Option::is_none")]
67    pub hidden: Option<bool>,
68    /// Id of the song.
69    pub id: u32,
70    /// If is instrumental song.
71    /// > Only in `get_song` with `user-core` level token
72    #[serde(skip_serializing_if = "Option::is_none")]
73    pub instrumental: Option<bool>,
74    /// If this song is a music lol
75    /// > Only in `get_song` with `user-core` level token
76    #[serde(skip_serializing_if = "Option::is_none")]
77    pub is_music: Option<bool>,
78    /// Literally lyrics.
79    /// > Only in `get_song` with `user-core` level token
80    #[serde(skip_serializing_if = "Option::is_none")]
81    pub lyrics: Option<Body>,
82    /// Id of the user who requested the lyrics.
83    pub lyrics_owner_id: u32,
84    /// Lyrics state.
85    pub lyrics_state: String,
86    /// Lyrics updated timestamp.
87    /// > Only in `get_song` with `user-core` level token
88    #[serde(skip_serializing_if = "Option::is_none")]
89    pub lyrics_updated_at: Option<u64>,
90    /// Path where is in genius.com website.
91    pub path: String,
92    /// Pending lyrics edits count.
93    /// > Only in `get_song` with `user-core` level token
94    #[serde(skip_serializing_if = "Option::is_none")]
95    pub pending_lyrics_edits_count: Option<u32>,
96    /// If is published?
97    /// > Only in `get_song` with `user-core` level token
98    #[serde(skip_serializing_if = "Option::is_none")]
99    pub published: Option<bool>,
100    /// > Only in `get_song` with `user-core` level token
101    #[serde(skip_serializing_if = "Option::is_none")]
102    pub pusher_channel: Option<String>,
103    /// Release date of the album in struct format [`Date`].
104    /// > Only in `get_song` with `user-core` level token
105    #[serde(skip_serializing_if = "Option::is_none")]
106    pub release_date_components: Option<Date>,
107    /// Number of pyongs in this song.
108    #[serde(skip_serializing_if = "Option::is_none")]
109    pub pyongs_count: Option<u32>,
110    /// The location of the recording.
111    /// > Only in `get_song`
112    #[serde(skip_serializing_if = "Option::is_none")]
113    pub recording_location: Option<String>,
114    /// Release date of this song in ISO 8601 date format.
115    /// > Only in `get_song`
116    #[serde(skip_serializing_if = "Option::is_none")]
117    pub release_date: Option<String>,
118    /// Release date in `{Month name} {day}, {year}` format.
119    /// > Only in `get_song`
120    #[serde(skip_serializing_if = "Option::is_none")]
121    pub release_date_for_display: Option<String>,
122    /// Share url.
123    /// > Only in `get_song` with `user-core` level token
124    #[serde(skip_serializing_if = "Option::is_none")]
125    pub share_url: Option<String>,
126    /// Song art image with a smaller size.
127    pub song_art_image_thumbnail_url: String,
128    /// Song art image.
129    pub song_art_image_url: String,
130    /// Soundcloud url.
131    /// > Only in `get_song` with `user-core` level token
132    #[serde(skip_serializing_if = "Option::is_none")]
133    pub soundcloud_url: Option<String>,
134    /// Spotify uuid.
135    /// > Only in `get_song` with `user-core` level token
136    #[serde(skip_serializing_if = "Option::is_none")]
137    pub spotify_uuid: Option<String>,
138    /// Information about contribution and views.
139    pub stats: SongStatus,
140    /// Title of the song.
141    pub title: String,
142    /// Title but with the featured artist if it exists.
143    pub title_with_featured: String,
144    /// > Only in `get_song` with `user-core` level token
145    #[serde(skip_serializing_if = "Option::is_none")]
146    pub tracking_paths: Option<TrackingPaths>,
147    /// Twitter share message
148    /// > Only in `get_song` with `user-core` level token
149    #[serde(skip_serializing_if = "Option::is_none")]
150    pub twitter_share_message: Option<String>,
151    /// Twitter share message without url.
152    /// > Only in `get_song` with `user-core` level token
153    #[serde(skip_serializing_if = "Option::is_none")]
154    pub twitter_share_message_without_url: Option<String>,
155    /// Updated by a human timestamp.
156    /// > Only in `get_song` with `user-core` level token
157    #[serde(skip_serializing_if = "Option::is_none")]
158    pub updated_by_human_at: Option<u64>,
159    /// Url of the song page.
160    pub url: String,
161    /// > Only in `get_song` with `user-core` level token
162    #[serde(skip_serializing_if = "Option::is_none")]
163    pub viewable_by_roles: Option<Vec<String>>,
164    /// Youtube start.
165    /// > Only in `get_song` with `user-core` level token
166    #[serde(skip_serializing_if = "Option::is_none")]
167    pub youtube_start: Option<String>,
168    /// Youtube url.
169    /// > Only in `get_song` with `user-core` level token
170    #[serde(skip_serializing_if = "Option::is_none")]
171    pub youtube_url: Option<String>,
172    /// User permissions and interactions.
173    /// > Only in `get_song`
174    #[serde(skip_serializing_if = "Option::is_none")]
175    pub current_user_metadata: Option<UserMetadata>,
176    /// Author of the song.
177    pub primary_artist: Artist,
178    /// Album of the song.
179    /// > Only in `get_song`
180    #[serde(skip_serializing_if = "Option::is_none")]
181    pub album: Option<Album>,
182    /// All albums that this song appears, I don't know why but yes.
183    /// > Only in `get_song` with `user-core` level token
184    #[serde(skip_serializing_if = "Option::is_none")]
185    pub albums: Option<Vec<Album>>,
186    /// People who worked in the music.
187    /// > Only in `get_song`
188    #[serde(skip_serializing_if = "Option::is_none")]
189    pub custom_performances: Option<Vec<SongPerformance>>,
190    /// Description annotation.
191    /// > Only in `get_song`
192    #[serde(skip_serializing_if = "Option::is_none")]
193    pub description_annotation: Option<Referent>,
194    /// Artists who featured in the song.
195    /// > Only in `get_song`
196    #[serde(skip_serializing_if = "Option::is_none")]
197    pub featured_artists: Option<Vec<Artist>>,
198    /// Music platforms that host this song and its url.
199    /// > Only in `get_song`
200    #[serde(skip_serializing_if = "Option::is_none")]
201    pub media: Option<Vec<SongMedia>>,
202    /// Artists who produced this song.
203    /// > Only in `get_song`
204    #[serde(skip_serializing_if = "Option::is_none")]
205    pub producer_artists: Option<Vec<Artist>>,
206    /// Songs that somehow relate to this.
207    /// > Only in `get_song`
208    #[serde(skip_serializing_if = "Option::is_none")]
209    pub song_relationships: Option<Vec<SongRelationship>>,
210    /// All Verified Annotation contributors.
211    /// > Only in `get_song`
212    #[serde(skip_serializing_if = "Option::is_none")]
213    pub verified_annotations_by: Option<Vec<User>>,
214    /// All verified contributors
215    /// > Only in `get_song`
216    #[serde(skip_serializing_if = "Option::is_none")]
217    pub verified_contributors: Option<Vec<SongContributor>>,
218    /// All Verified lyrics contributors.
219    /// > Only in `get_song`
220    #[serde(skip_serializing_if = "Option::is_none")]
221    pub verified_lyrics_by: Option<Vec<User>>,
222    /// Composers
223    /// > Only in `get_song`
224    #[serde(skip_serializing_if = "Option::is_none")]
225    pub writer_artists: Option<Vec<Artist>>,
226}
227
228#[derive(Serialize, Deserialize, Debug)]
229pub struct TrackingPaths {
230    pub aggregate: String,
231    pub concurrent: String,
232}
233
234#[derive(Serialize, Deserialize, Debug)]
235pub struct SongContributor {
236    pub contributions: Vec<String>,
237    pub artist: Artist,
238    #[serde(skip_serializing_if = "Option::is_none")]
239    pub user: Option<User>,
240}
241
242#[derive(Serialize, Deserialize, Debug)]
243pub struct SongRelationship {
244    /// The type of relationship can be `samples`, `sampled_in`, `interpolates`, `interpolated_by`, `cover_of`, `covered_by`, `remix_of`, `remixed_by`, `live_version_of` and `performed_live_as`.
245    pub relationship_type: String,
246    /// Songs with this relationship type.
247    pub songs: Vec<Option<Song>>,
248}
249
250#[derive(Serialize, Deserialize, Debug)]
251pub struct SongPerformance {
252    pub label: String,
253    pub artists: Vec<Artist>,
254}
255
256#[derive(Serialize, Deserialize, Debug)]
257pub struct SongMedia {
258    /// Spotify path of the song with `:` instead `/`, weird.
259    #[serde(skip_serializing_if = "Option::is_none")]
260    pub native_uri: Option<String>,
261    /// Soundcloud username.
262    #[serde(skip_serializing_if = "Option::is_none")]
263    pub attribution: Option<String>,
264    /// The song host provider `youtube`, `soundcloud` or `spotify`.
265    pub provider: String,
266    /// Youtube position of the video that starts the music.
267    #[serde(skip_serializing_if = "Option::is_none")]
268    pub start: Option<u32>,
269    /// Media type `video` or `audio`
270    #[serde(rename = "type")]
271    pub media_type: String,
272    /// The url of the song in the media host.
273    pub url: String,
274}
275
276#[derive(Serialize, Deserialize, Debug)]
277pub struct SongStatus {
278    /// Number of annotations accepted on this song.
279    #[serde(skip_serializing_if = "Option::is_none")]
280    pub accepted_annotations: Option<u32>,
281    /// Number of contributors.
282    #[serde(skip_serializing_if = "Option::is_none")]
283    pub contributors: Option<u32>,
284    /// Number of users who have earned iq.
285    #[serde(skip_serializing_if = "Option::is_none")]
286    pub iq_earners: Option<u32>,
287    /// Number of transcribers.
288    #[serde(skip_serializing_if = "Option::is_none")]
289    pub transcribers: Option<u32>,
290    /// Number of verified annotations.
291    #[serde(skip_serializing_if = "Option::is_none")]
292    pub verified_annotations: Option<u32>,
293    /// Number of unreviewed annotations.
294    pub unreviewed_annotations: u32,
295    /// If it's hot be careful with your hands.
296    pub hot: bool,
297    /// Number of page views
298    #[serde(skip_serializing_if = "Option::is_none")]
299    pub pageviews: Option<u32>,
300}
301
302#[derive(Serialize, Deserialize, Debug)]
303pub struct Artist {
304    /// Path of the API.
305    pub api_path: String,
306    /// Artist header image.
307    pub header_image_url: String,
308    /// Artist id.
309    pub id: u32,
310    /// Artist image.
311    pub image_url: String,
312    /// First letter of the artist name.
313    /// > Only with `user-core` level token
314    #[serde(skip_serializing_if = "Option::is_none")]
315    pub index_character: Option<char>,
316    /// Is this artist a meme?
317    pub is_meme_verified: bool,
318    /// If this artist is verified.
319    pub is_verified: bool,
320    /// Name of the artist.
321    pub name: String,
322    /// > Only with `user-core` level token
323    #[serde(skip_serializing_if = "Option::is_none")]
324    pub slug: Option<String>,
325    /// Url of the artist page.
326    pub url: String,
327    /// How much iq this artist has.
328    #[serde(skip_serializing_if = "Option::is_none")]
329    pub iq: Option<u32>,
330}