Skip to main content

lastfm_client/types/
users.rs

1use serde::Deserialize;
2
3use crate::types::utils::{bool_from_str, u32_from_str};
4
5// ── Internal deserialization helpers ─────────────────────────────────────────
6
7/// The `registered` field in a user.getInfo response
8#[derive(Deserialize, Debug)]
9struct RegisteredRaw {
10    #[serde(rename = "unixtime", deserialize_with = "u32_from_str")]
11    unixtime: u32,
12}
13
14/// Top-level envelope for user.getInfo
15#[derive(Deserialize, Debug)]
16pub(crate) struct UserInfoResponse {
17    user: UserInfoRaw,
18}
19
20#[derive(Deserialize, Debug)]
21struct UserInfoRaw {
22    name: String,
23    realname: String,
24    url: String,
25    country: String,
26    #[serde(deserialize_with = "u32_from_str")]
27    age: u32,
28    gender: String,
29    #[serde(deserialize_with = "bool_from_str")]
30    subscriber: bool,
31    #[serde(deserialize_with = "u32_from_str")]
32    playcount: u32,
33    #[serde(deserialize_with = "u32_from_str")]
34    playlists: u32,
35    registered: RegisteredRaw,
36}
37
38// ── Public type ───────────────────────────────────────────────────────────────
39
40/// Profile information for a Last.fm user.
41///
42/// Returned by [`user.getInfo`](https://www.last.fm/api/show/user.getInfo).
43#[derive(Debug, Clone)]
44#[non_exhaustive]
45pub struct UserInfo {
46    /// Last.fm username
47    pub name: String,
48    /// Real name as set by the user
49    pub real_name: String,
50    /// URL to the user's Last.fm profile page
51    pub url: String,
52    /// Country code (e.g. `"France"`)
53    pub country: String,
54    /// Age
55    pub age: u32,
56    /// Gender (`"m"`, `"f"`, or `""`)
57    pub gender: String,
58    /// Whether the user has a Last.fm Pro subscription
59    pub subscriber: bool,
60    /// Total number of scrobbles
61    pub play_count: u32,
62    /// Number of playlists
63    pub playlist_count: u32,
64    /// Account registration date as a Unix timestamp
65    pub registered: u32,
66}
67
68impl From<UserInfoRaw> for UserInfo {
69    fn from(r: UserInfoRaw) -> Self {
70        Self {
71            name: r.name,
72            real_name: r.realname,
73            url: r.url,
74            country: r.country,
75            age: r.age,
76            gender: r.gender,
77            subscriber: r.subscriber,
78            play_count: r.playcount,
79            playlist_count: r.playlists,
80            registered: r.registered.unixtime,
81        }
82    }
83}
84
85impl From<UserInfoResponse> for UserInfo {
86    fn from(r: UserInfoResponse) -> Self {
87        Self::from(r.user)
88    }
89}