Skip to main content

lastfm_client/types/
friends.rs

1use serde::Deserialize;
2
3use crate::types::TrackImage;
4use crate::types::utils::{bool_from_str, u32_from_str};
5
6// ── Internal deserialization helpers ─────────────────────────────────────────
7
8#[derive(Deserialize, Debug)]
9pub(crate) struct FriendsResponse {
10    friends: FriendsRaw,
11}
12
13#[derive(Deserialize, Debug)]
14struct FriendsRaw {
15    user: Vec<FriendRaw>,
16    #[serde(rename = "@attr")]
17    attr: FriendsAttr,
18}
19
20#[derive(Deserialize, Debug)]
21struct FriendsAttr {
22    #[serde(deserialize_with = "u32_from_str")]
23    total: u32,
24    #[serde(deserialize_with = "u32_from_str")]
25    page: u32,
26    #[serde(rename = "totalPages", deserialize_with = "u32_from_str")]
27    total_pages: u32,
28    #[serde(rename = "perPage", deserialize_with = "u32_from_str")]
29    per_page: u32,
30}
31
32#[derive(Deserialize, Debug)]
33struct RegisteredRaw {
34    #[serde(rename = "unixtime", deserialize_with = "u32_from_str")]
35    unixtime: u32,
36}
37
38#[derive(Deserialize, Debug)]
39struct FriendRaw {
40    name: String,
41    realname: String,
42    url: String,
43    country: String,
44    #[serde(deserialize_with = "bool_from_str")]
45    subscriber: bool,
46    image: Vec<TrackImage>,
47    registered: RegisteredRaw,
48}
49
50// ── Public types ──────────────────────────────────────────────────────────────
51
52/// Profile information for a Last.fm friend.
53///
54/// Returned by [`user.getFriends`](https://www.last.fm/api/show/user.getFriends).
55#[derive(Debug, Clone)]
56#[non_exhaustive]
57pub struct FriendProfile {
58    /// Last.fm username
59    pub name: String,
60    /// Real name as set by the user
61    pub real_name: String,
62    /// Last.fm profile URL
63    pub url: String,
64    /// Country
65    pub country: String,
66    /// Whether the user has a Last.fm Pro subscription
67    pub subscriber: bool,
68    /// Profile images in various sizes
69    pub images: Vec<TrackImage>,
70    /// Account registration date as a Unix timestamp
71    pub registered: u32,
72}
73
74impl From<FriendRaw> for FriendProfile {
75    fn from(r: FriendRaw) -> Self {
76        Self {
77            name: r.name,
78            real_name: r.realname,
79            url: r.url,
80            country: r.country,
81            subscriber: r.subscriber,
82            images: r.image,
83            registered: r.registered.unixtime,
84        }
85    }
86}
87
88/// Paginated response from `user.getFriends`
89#[derive(Debug)]
90#[non_exhaustive]
91pub struct FriendsPage {
92    /// The friends on this page
93    pub friends: Vec<FriendProfile>,
94    /// Total number of friends
95    pub total: u32,
96    /// Current page number (1-indexed)
97    pub page: u32,
98    /// Total number of pages
99    pub total_pages: u32,
100    /// Number of results per page
101    pub per_page: u32,
102}
103
104impl From<FriendsResponse> for FriendsPage {
105    fn from(r: FriendsResponse) -> Self {
106        Self {
107            total: r.friends.attr.total,
108            page: r.friends.attr.page,
109            total_pages: r.friends.attr.total_pages,
110            per_page: r.friends.attr.per_page,
111            friends: r
112                .friends
113                .user
114                .into_iter()
115                .map(FriendProfile::from)
116                .collect(),
117        }
118    }
119}