Skip to main content

lastfm_client/types/
weekly.rs

1use serde::Deserialize;
2
3use crate::types::utils::u32_from_str;
4
5// ── WeeklyChartList ───────────────────────────────────────────────────────────
6
7#[derive(Deserialize, Debug)]
8pub(crate) struct WeeklyChartListResponse {
9    weeklychartlist: WeeklyChartListRaw,
10}
11
12#[derive(Deserialize, Debug)]
13struct WeeklyChartListRaw {
14    chart: Vec<WeeklyChartRangeRaw>,
15}
16
17#[derive(Deserialize, Debug)]
18struct WeeklyChartRangeRaw {
19    #[serde(deserialize_with = "u32_from_str")]
20    from: u32,
21    #[serde(deserialize_with = "u32_from_str")]
22    to: u32,
23}
24
25/// A time range representing a weekly chart period.
26///
27/// Returned as part of [`user.getWeeklyChartList`](https://www.last.fm/api/show/user.getWeeklyChartList).
28#[derive(Debug, Clone)]
29#[non_exhaustive]
30pub struct WeeklyChartRange {
31    /// Start of the week as a Unix timestamp
32    pub from: u32,
33    /// End of the week as a Unix timestamp
34    pub to: u32,
35}
36
37impl From<WeeklyChartRangeRaw> for WeeklyChartRange {
38    fn from(r: WeeklyChartRangeRaw) -> Self {
39        Self {
40            from: r.from,
41            to: r.to,
42        }
43    }
44}
45
46impl From<WeeklyChartListResponse> for Vec<WeeklyChartRange> {
47    fn from(r: WeeklyChartListResponse) -> Self {
48        r.weeklychartlist
49            .chart
50            .into_iter()
51            .map(WeeklyChartRange::from)
52            .collect()
53    }
54}
55
56// ── WeeklyTrackChart ──────────────────────────────────────────────────────────
57
58#[derive(Deserialize, Debug)]
59pub(crate) struct WeeklyTrackChartResponse {
60    weeklytrackchart: WeeklyTrackChartRaw,
61}
62
63#[derive(Deserialize, Debug)]
64struct WeeklyTrackChartRaw {
65    track: Vec<WeeklyTrackRaw>,
66}
67
68#[derive(Deserialize, Debug)]
69struct WeeklyTrackRaw {
70    name: String,
71    mbid: String,
72    url: String,
73    #[serde(deserialize_with = "u32_from_str")]
74    playcount: u32,
75    artist: WeeklyArtistRef,
76    #[serde(rename = "@attr")]
77    attr: WeeklyRankAttr,
78}
79
80#[derive(Deserialize, Debug)]
81struct WeeklyArtistRef {
82    #[serde(rename = "#text")]
83    name: String,
84    mbid: String,
85}
86
87#[derive(Deserialize, Debug)]
88struct WeeklyRankAttr {
89    #[serde(deserialize_with = "u32_from_str")]
90    rank: u32,
91}
92
93/// A track entry in a weekly track chart.
94///
95/// Returned by [`user.getWeeklyTrackChart`](https://www.last.fm/api/show/user.getWeeklyTrackChart).
96#[derive(Debug, Clone)]
97#[non_exhaustive]
98pub struct WeeklyTrack {
99    /// Track title
100    pub name: String,
101    /// `MusicBrainz` track identifier (may be empty)
102    pub mbid: String,
103    /// Last.fm URL for this track
104    pub url: String,
105    /// Number of plays in this week
106    pub playcount: u32,
107    /// Artist name
108    pub artist_name: String,
109    /// `MusicBrainz` artist identifier (may be empty)
110    pub artist_mbid: String,
111    /// Position in the chart (1-indexed)
112    pub rank: u32,
113}
114
115impl From<WeeklyTrackRaw> for WeeklyTrack {
116    fn from(r: WeeklyTrackRaw) -> Self {
117        Self {
118            name: r.name,
119            mbid: r.mbid,
120            url: r.url,
121            playcount: r.playcount,
122            artist_name: r.artist.name,
123            artist_mbid: r.artist.mbid,
124            rank: r.attr.rank,
125        }
126    }
127}
128
129impl From<WeeklyTrackChartResponse> for Vec<WeeklyTrack> {
130    fn from(r: WeeklyTrackChartResponse) -> Self {
131        r.weeklytrackchart
132            .track
133            .into_iter()
134            .map(WeeklyTrack::from)
135            .collect()
136    }
137}
138
139// ── WeeklyArtistChart ─────────────────────────────────────────────────────────
140
141#[derive(Deserialize, Debug)]
142pub(crate) struct WeeklyArtistChartResponse {
143    weeklyartistchart: WeeklyArtistChartRaw,
144}
145
146#[derive(Deserialize, Debug)]
147struct WeeklyArtistChartRaw {
148    artist: Vec<WeeklyArtistRaw>,
149}
150
151#[derive(Deserialize, Debug)]
152struct WeeklyArtistRaw {
153    name: String,
154    mbid: String,
155    url: String,
156    #[serde(deserialize_with = "u32_from_str")]
157    playcount: u32,
158    #[serde(rename = "@attr")]
159    attr: WeeklyRankAttr,
160}
161
162/// An artist entry in a weekly artist chart.
163///
164/// Returned by [`user.getWeeklyArtistChart`](https://www.last.fm/api/show/user.getWeeklyArtistChart).
165#[derive(Debug, Clone)]
166#[non_exhaustive]
167pub struct WeeklyArtist {
168    /// Artist name
169    pub name: String,
170    /// `MusicBrainz` artist identifier (may be empty)
171    pub mbid: String,
172    /// Last.fm URL for this artist
173    pub url: String,
174    /// Number of plays in this week
175    pub playcount: u32,
176    /// Position in the chart (1-indexed)
177    pub rank: u32,
178}
179
180impl From<WeeklyArtistRaw> for WeeklyArtist {
181    fn from(r: WeeklyArtistRaw) -> Self {
182        Self {
183            name: r.name,
184            mbid: r.mbid,
185            url: r.url,
186            playcount: r.playcount,
187            rank: r.attr.rank,
188        }
189    }
190}
191
192impl From<WeeklyArtistChartResponse> for Vec<WeeklyArtist> {
193    fn from(r: WeeklyArtistChartResponse) -> Self {
194        r.weeklyartistchart
195            .artist
196            .into_iter()
197            .map(WeeklyArtist::from)
198            .collect()
199    }
200}
201
202// ── WeeklyAlbumChart ──────────────────────────────────────────────────────────
203
204#[derive(Deserialize, Debug)]
205pub(crate) struct WeeklyAlbumChartResponse {
206    weeklyalbumchart: WeeklyAlbumChartRaw,
207}
208
209#[derive(Deserialize, Debug)]
210struct WeeklyAlbumChartRaw {
211    album: Vec<WeeklyAlbumRaw>,
212}
213
214#[derive(Deserialize, Debug)]
215struct WeeklyAlbumRaw {
216    name: String,
217    mbid: String,
218    url: String,
219    #[serde(deserialize_with = "u32_from_str")]
220    playcount: u32,
221    artist: WeeklyArtistRef,
222    #[serde(rename = "@attr")]
223    attr: WeeklyRankAttr,
224}
225
226/// An album entry in a weekly album chart.
227///
228/// Returned by [`user.getWeeklyAlbumChart`](https://www.last.fm/api/show/user.getWeeklyAlbumChart).
229#[derive(Debug, Clone)]
230#[non_exhaustive]
231pub struct WeeklyAlbum {
232    /// Album title
233    pub name: String,
234    /// `MusicBrainz` album identifier (may be empty)
235    pub mbid: String,
236    /// Last.fm URL for this album
237    pub url: String,
238    /// Number of plays in this week
239    pub playcount: u32,
240    /// Artist name
241    pub artist_name: String,
242    /// `MusicBrainz` artist identifier (may be empty)
243    pub artist_mbid: String,
244    /// Position in the chart (1-indexed)
245    pub rank: u32,
246}
247
248impl From<WeeklyAlbumRaw> for WeeklyAlbum {
249    fn from(r: WeeklyAlbumRaw) -> Self {
250        Self {
251            name: r.name,
252            mbid: r.mbid,
253            url: r.url,
254            playcount: r.playcount,
255            artist_name: r.artist.name,
256            artist_mbid: r.artist.mbid,
257            rank: r.attr.rank,
258        }
259    }
260}
261
262impl From<WeeklyAlbumChartResponse> for Vec<WeeklyAlbum> {
263    fn from(r: WeeklyAlbumChartResponse) -> Self {
264        r.weeklyalbumchart
265            .album
266            .into_iter()
267            .map(WeeklyAlbum::from)
268            .collect()
269    }
270}