rspotify_model/
lib.rs

1//! All Spotify API endpoint response objects. Please refer to the endpoints
2//! where they are used for a link to their reference in the Spotify API
3//! documentation.
4pub mod album;
5pub mod artist;
6pub mod audio;
7pub mod auth;
8pub mod category;
9pub mod context;
10pub(crate) mod custom_serde;
11pub mod device;
12pub mod enums;
13pub mod error;
14pub mod idtypes;
15pub mod image;
16pub mod offset;
17pub mod page;
18pub mod playing;
19pub mod playlist;
20pub mod recommend;
21pub mod search;
22pub mod show;
23pub mod track;
24pub mod user;
25
26pub use {
27    album::*, artist::*, audio::*, auth::*, category::*, context::*, device::*, enums::*, error::*,
28    idtypes::*, image::*, offset::*, page::*, playing::*, playlist::*, recommend::*, search::*,
29    show::*, track::*, user::*,
30};
31
32use serde::{Deserialize, Serialize};
33
34/// Followers object
35#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Default)]
36pub struct Followers {
37    // This field will always set to null, as the Web API does not support it at the moment.
38    // pub href: Option<String>,
39    pub total: u32,
40}
41
42/// A full track object or a full episode object
43#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
44#[serde(untagged)]
45pub enum PlayableItem {
46    Track(track::FullTrack),
47    Episode(show::FullEpisode),
48}
49
50impl PlayableItem {
51    /// Utility to get the ID from either variant in the enum.
52    ///
53    /// Note that if it's a track and if it's local, it may not have an ID, in
54    /// which case this function will return `None`.
55    #[must_use]
56    pub fn id(&self) -> Option<PlayableId<'_>> {
57        match self {
58            PlayableItem::Track(t) => t.id.as_ref().map(|t| PlayableId::Track(t.as_ref())),
59            PlayableItem::Episode(e) => Some(PlayableId::Episode(e.id.as_ref())),
60        }
61    }
62}
63
64#[cfg(test)]
65mod tests {
66    use super::*;
67
68    #[test]
69    fn test_get_id() {
70        // Assert artist
71        let artist_id = "spotify:artist:2WX2uTcsvV5OnS0inACecP";
72        let id = ArtistId::from_id_or_uri(artist_id).unwrap();
73        assert_eq!("2WX2uTcsvV5OnS0inACecP", id.id());
74
75        // Assert album
76        let album_id_a = "spotify/album/2WX2uTcsvV5OnS0inACecP";
77        assert_eq!(
78            "2WX2uTcsvV5OnS0inACecP",
79            AlbumId::from_id_or_uri(album_id_a).unwrap().id()
80        );
81
82        // Mismatch type
83        assert_eq!(
84            Err(IdError::InvalidType),
85            ArtistId::from_id_or_uri(album_id_a)
86        );
87
88        // Could not split
89        let artist_id_c = "spotify-album-2WX2uTcsvV5OnS0inACecP";
90        assert_eq!(
91            Err(IdError::InvalidId),
92            ArtistId::from_id_or_uri(artist_id_c)
93        );
94
95        let playlist_id = "spotify:playlist:59ZbFPES4DQwEjBpWHzrtC";
96        assert_eq!(
97            "59ZbFPES4DQwEjBpWHzrtC",
98            PlaylistId::from_id_or_uri(playlist_id).unwrap().id()
99        );
100    }
101
102    #[test]
103    fn test_get_uri() {
104        let track_id1 = "spotify:track:4iV5W9uYEdYUVa79Axb7Rh";
105        let track_id2 = "1301WleyT98MSxVHPZCA6M";
106        let id1 = TrackId::from_id_or_uri(track_id1).unwrap();
107        let id2 = TrackId::from_id_or_uri(track_id2).unwrap();
108        assert_eq!(track_id1, &id1.uri());
109        assert_eq!("spotify:track:1301WleyT98MSxVHPZCA6M", &id2.uri());
110    }
111}