1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
use std::collections::HashMap;

use serde::{Deserialize, Serialize};

use crate::model::{Followers, Image, TypeUser};

macro_rules! inherit_user_simplified {
    ($(#[$attr:meta])* $name:ident { $($(#[$f_attr:meta])* $f_name:ident : $f_ty:ty,)* }) => {
        to_struct!($(#[$attr])* $name {
            $(
                $(#[$f_attr])*
                $f_name: $f_ty,
            )*
            /// The name of the user; can be not available.
            display_name: Option<String>,
            /// Known public external URLs for this user.
            external_urls: HashMap<String, String>,
            /// The [Spotify user
            /// ID](https://developer.spotify.com/documentation/web-api/#spotify-uris-and-ids) for the
            /// user.
            id: String,
            /// The item type; `user`.
            #[serde(rename = "type")]
            item_type: TypeUser,
        });
    }
}

inherit_user_simplified!(
    /// A user object that contains less fields than UserPublic and is not documented anywhere, but
    /// is returned by some endpoints.
    UserSimplified {}
);

macro_rules! inherit_user_public {
    ($(#[$attr:meta])* $name:ident { $($(#[$f_attr:meta])* $f_name:ident : $f_ty:ty,)* }) => {
        inherit_user_simplified!($(#[$attr])* $name {
            $(
                $(#[$f_attr])*
                $f_name: $f_ty,
            )*
            /// Information about the followers of the user.
            followers: Followers,
            /// The user's profile image.
            images: Vec<Image>,
        });
    }
}

inherit_user_public!(
    /// A user object that is accessible to everyone.
    UserPublic {}
);
inherit_user_public!(
    /// A user object only accessible to the user themselves; does not work with Client Credentials
    /// flow.
    UserPrivate {
        /// The country of the user, as set in their account profile. Requires `user-read-private`.
        /// This is an ISO 3166 2-letter country code.
        country: Option<String>,
        /// The user's email address, which is not necessarily a real email address. Requires
        /// `user-read-email`.
        email: Option<String>,
        /// The user's Spotify subscription level. Requires `user-read-private`.
        product: Option<Subscription>,
    }
);

impl UserPublic {
    /// Convert to a `UserSimplified`.
    #[must_use]
    pub fn simplify(self) -> UserSimplified {
        UserSimplified {
            display_name: self.display_name,
            external_urls: self.external_urls,
            id: self.id,
            item_type: TypeUser,
        }
    }
}
impl From<UserPublic> for UserSimplified {
    fn from(user: UserPublic) -> Self {
        user.simplify()
    }
}
impl UserPrivate {
    /// Convert to a `UserPublic`.
    #[must_use]
    pub fn publicize(self) -> UserPublic {
        UserPublic {
            display_name: self.display_name,
            external_urls: self.external_urls,
            id: self.id,
            followers: self.followers,
            images: self.images,
            item_type: TypeUser,
        }
    }
    /// Convert to a `UserSimplified`.
    #[must_use]
    pub fn simplify(self) -> UserSimplified {
        self.publicize().simplify()
    }
}
impl From<UserPrivate> for UserSimplified {
    fn from(user: UserPrivate) -> Self {
        user.simplify()
    }
}

/// The subscription level; premium or free.
#[derive(Debug, Clone, PartialEq, Eq, Copy, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum Subscription {
    /// The user is subscribed to Spotify Premium.
    Premium,
    /// The user isn't subscribed to Spotify Premium. Also known as `open`.
    #[serde(alias = "open")]
    Free,
}