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}
42
43/// Track link object
44/// [track-relinking](https://developer.spotify.com/documentation/web-api/concepts/track-relinking)
45#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
46pub struct TrackLink {
47    pub external_urls: HashMap<String, String>,
48    pub href: String,
49    pub id: Option<TrackId<'static>>,
50    pub r#type: Type,
51    pub uri: String,
52}
53
54/// Intermediate full track wrapped by `Vec`
55#[derive(Deserialize)]
56pub struct FullTracks {
57    pub tracks: Vec<FullTrack>,
58}
59
60/// Simplified track object.
61///
62/// `is_playable`, `linked_from` and `restrictions` will only be present when
63/// relinking is applied.
64#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
65pub struct SimplifiedTrack {
66    #[serde(skip_serializing_if = "Option::is_none")]
67    pub album: Option<SimplifiedAlbum>,
68    pub artists: Vec<SimplifiedArtist>,
69    pub available_markets: Option<Vec<String>>,
70    pub disc_number: i32,
71    #[serde(with = "duration_ms", rename = "duration_ms")]
72    pub duration: Duration,
73    pub explicit: bool,
74    pub external_urls: HashMap<String, String>,
75    #[serde(default)]
76    pub href: Option<String>,
77    pub id: Option<TrackId<'static>>,
78    pub is_local: bool,
79    pub is_playable: Option<bool>,
80    pub linked_from: Option<TrackLink>,
81    pub restrictions: Option<Restriction>,
82    pub name: String,
83    pub preview_url: Option<String>,
84    pub track_number: u32,
85}
86
87/// Saved track object
88#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
89pub struct SavedTrack {
90    pub added_at: DateTime<Utc>,
91    pub track: FullTrack,
92}
93
94/// Track id with specific positions track in a playlist
95///
96/// This is a short-lived struct for endpoint parameters, so it uses
97/// `PlayableId<'a>` instead of `PlayableId<'static>` to avoid the unnecessary
98/// allocation. Same goes for the positions slice instead of vector.
99pub struct ItemPositions<'a> {
100    pub id: PlayableId<'a>,
101    pub positions: &'a [u32],
102}