rspotify_model/
track.rs

1//! All kinds of tracks object
2
3use chrono::prelude::*;
4use chrono::Duration;
5use serde::{Deserialize, Serialize};
6
7use std::collections::HashMap;
8
9use crate::{
10    custom_serde::duration_ms, PlayableId, Restriction, SimplifiedAlbum, SimplifiedArtist, TrackId,
11    Type,
12};
13
14/// Full track object
15#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
16pub struct FullTrack {
17    pub album: SimplifiedAlbum,
18    pub artists: Vec<SimplifiedArtist>,
19    #[serde(skip_serializing_if = "Vec::is_empty", default)]
20    pub available_markets: Vec<String>,
21    pub disc_number: i32,
22    #[serde(with = "duration_ms", rename = "duration_ms")]
23    pub duration: Duration,
24    pub explicit: bool,
25    pub external_ids: HashMap<String, String>,
26    pub external_urls: HashMap<String, String>,
27    pub href: Option<String>,
28    /// Note that a track may not have an ID/URI if it's local
29    pub id: Option<TrackId<'static>>,
30    pub is_local: bool,
31    #[serde(skip_serializing_if = "Option::is_none")]
32    pub is_playable: Option<bool>,
33    #[serde(skip_serializing_if = "Option::is_none")]
34    pub linked_from: Option<TrackLink>,
35    #[serde(skip_serializing_if = "Option::is_none")]
36    pub restrictions: Option<Restriction>,
37    pub name: String,
38    pub popularity: u32,
39    pub preview_url: Option<String>,
40    pub track_number: u32,
41    pub r#type: Type,
42}
43
44/// Track link object
45/// [track-relinking](https://developer.spotify.com/documentation/web-api/concepts/track-relinking)
46#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
47pub struct TrackLink {
48    pub external_urls: HashMap<String, String>,
49    pub href: String,
50    pub id: Option<TrackId<'static>>,
51    pub r#type: Type,
52    pub uri: String,
53}
54
55/// Intermediate full track wrapped by `Vec`
56#[derive(Deserialize)]
57pub struct FullTracks {
58    pub tracks: Vec<FullTrack>,
59}
60
61/// Simplified track object.
62///
63/// `is_playable`, `linked_from` and `restrictions` will only be present when
64/// relinking is applied.
65#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
66pub struct SimplifiedTrack {
67    #[serde(skip_serializing_if = "Option::is_none")]
68    pub album: Option<SimplifiedAlbum>,
69    pub artists: Vec<SimplifiedArtist>,
70    pub available_markets: Option<Vec<String>>,
71    pub disc_number: i32,
72    #[serde(with = "duration_ms", rename = "duration_ms")]
73    pub duration: Duration,
74    pub explicit: bool,
75    pub external_urls: HashMap<String, String>,
76    #[serde(default)]
77    pub href: Option<String>,
78    pub id: Option<TrackId<'static>>,
79    pub is_local: bool,
80    pub is_playable: Option<bool>,
81    pub linked_from: Option<TrackLink>,
82    pub restrictions: Option<Restriction>,
83    pub name: String,
84    pub preview_url: Option<String>,
85    pub track_number: u32,
86}
87
88/// Saved track object
89#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
90pub struct SavedTrack {
91    pub added_at: DateTime<Utc>,
92    pub track: FullTrack,
93}
94
95/// Track id with specific positions track in a playlist
96///
97/// This is a short-lived struct for endpoint parameters, so it uses
98/// `PlayableId<'a>` instead of `PlayableId<'static>` to avoid the unnecessary
99/// allocation. Same goes for the positions slice instead of vector.
100pub struct ItemPositions<'a> {
101    pub id: PlayableId<'a>,
102    pub positions: &'a [u32],
103}