spotify_rs/endpoint/
album.rs

1use serde::Serialize;
2
3use crate::{
4    auth::{AuthFlow, Authorised},
5    body_list,
6    error::Result,
7    model::{
8        album::{Album, Albums, PagedAlbums, SavedAlbum, SimplifiedAlbum},
9        track::SimplifiedTrack,
10        Page,
11    },
12    query_list, Nil,
13};
14
15use super::{Client, Endpoint};
16
17impl Endpoint for AlbumEndpoint {}
18impl Endpoint for AlbumsEndpoint {}
19impl Endpoint for AlbumTracksEndpoint {}
20impl Endpoint for SavedAlbumsEndpoint {}
21impl Endpoint for NewReleasesEndpoint {}
22
23pub fn album(id: impl Into<String>) -> AlbumEndpoint {
24    AlbumEndpoint {
25        id: id.into(),
26        market: None,
27    }
28}
29
30pub fn albums<T: AsRef<str>>(ids: &[T]) -> AlbumsEndpoint {
31    AlbumsEndpoint {
32        ids: query_list(ids),
33        market: None,
34    }
35}
36
37pub fn album_tracks(album_id: impl Into<String>) -> AlbumTracksEndpoint {
38    AlbumTracksEndpoint {
39        id: album_id.into(),
40        ..Default::default()
41    }
42}
43
44pub fn saved_albums() -> SavedAlbumsEndpoint {
45    SavedAlbumsEndpoint::default()
46}
47
48pub async fn save_albums<T: AsRef<str>>(
49    ids: &[T],
50    spotify: &Client<impl AuthFlow + Authorised>,
51) -> Result<Nil> {
52    spotify
53        .put("/me/albums".to_owned(), body_list("ids", ids))
54        .await
55}
56
57pub async fn remove_saved_albums<T: AsRef<str>>(
58    ids: &[T],
59    spotify: &Client<impl AuthFlow + Authorised>,
60) -> Result<Nil> {
61    spotify
62        .delete("/me/albums".to_owned(), body_list("ids", ids))
63        .await
64}
65
66pub async fn check_saved_albums<T: AsRef<str>>(
67    ids: &[T],
68    spotify: &Client<impl AuthFlow + Authorised>,
69) -> Result<Vec<bool>> {
70    spotify
71        .get("/me/albums/contains".to_owned(), [("ids", query_list(ids))])
72        .await
73}
74
75pub fn new_releases() -> NewReleasesEndpoint {
76    NewReleasesEndpoint::default()
77}
78
79/// Endpoint for getting a single album.
80#[derive(Clone, Debug, Default, Serialize)]
81pub struct AlbumEndpoint {
82    #[serde(skip)]
83    pub(crate) id: String,
84    pub(crate) market: Option<String>,
85}
86
87impl AlbumEndpoint {
88    #[doc = include_str!("../docs/market.md")]
89    pub fn market(mut self, market: impl Into<String>) -> Self {
90        self.market = Some(market.into());
91        self
92    }
93
94    #[doc = include_str!("../docs/send.md")]
95    pub async fn get(self, spotify: &Client<impl AuthFlow>) -> Result<Album> {
96        spotify.get(format!("/albums/{}", self.id), self).await
97    }
98}
99
100#[derive(Clone, Debug, Default, Serialize)]
101pub struct AlbumsEndpoint {
102    pub(crate) ids: String,
103    pub(crate) market: Option<String>,
104}
105
106impl AlbumsEndpoint {
107    #[doc = include_str!("../docs/market.md")]
108    pub fn market(mut self, market: impl Into<String>) -> Self {
109        self.market = Some(market.into());
110        self
111    }
112
113    #[doc = include_str!("../docs/send.md")]
114    pub async fn get(self, spotify: &Client<impl AuthFlow>) -> Result<Vec<Album>> {
115        spotify
116            .get("/albums".to_owned(), self)
117            .await
118            .map(|a: Albums| a.albums)
119    }
120}
121
122#[derive(Clone, Debug, Default, Serialize)]
123pub struct AlbumTracksEndpoint {
124    #[serde(skip)]
125    pub(crate) id: String,
126    pub(crate) market: Option<String>,
127    pub(crate) limit: Option<u32>,
128    pub(crate) offset: Option<u32>,
129}
130
131impl AlbumTracksEndpoint {
132    #[doc = include_str!("../docs/market.md")]
133    pub fn market(mut self, market: impl Into<String>) -> Self {
134        self.market = Some(market.into());
135        self
136    }
137
138    #[doc = include_str!("../docs/limit.md")]
139    pub fn limit(mut self, limit: u32) -> Self {
140        self.limit = Some(limit);
141        self
142    }
143
144    #[doc = include_str!("../docs/offset.md")]
145    pub fn offset(mut self, offset: u32) -> Self {
146        self.offset = Some(offset);
147        self
148    }
149
150    #[doc = include_str!("../docs/send.md")]
151    pub async fn get(self, spotify: &Client<impl AuthFlow>) -> Result<Page<SimplifiedTrack>> {
152        spotify
153            .get(format!("/albums/{}/tracks", self.id), self)
154            .await
155    }
156}
157
158#[derive(Clone, Debug, Default, Serialize)]
159pub struct SavedAlbumsEndpoint {
160    pub(crate) market: Option<String>,
161    pub(crate) limit: Option<u32>,
162    pub(crate) offset: Option<u32>,
163}
164
165impl SavedAlbumsEndpoint {
166    #[doc = include_str!("../docs/market.md")]
167    pub fn market(mut self, market: impl Into<String>) -> Self {
168        self.market = Some(market.into());
169        self
170    }
171
172    #[doc = include_str!("../docs/limit.md")]
173    pub fn limit(mut self, limit: u32) -> Self {
174        self.limit = Some(limit);
175        self
176    }
177
178    #[doc = include_str!("../docs/offset.md")]
179    pub fn offset(mut self, offset: u32) -> Self {
180        self.offset = Some(offset);
181        self
182    }
183
184    #[doc = include_str!("../docs/send.md")]
185    pub async fn get(
186        self,
187        spotify: &Client<impl AuthFlow + Authorised>,
188    ) -> Result<Page<SavedAlbum>> {
189        spotify.get("/me/albums".to_owned(), self).await
190    }
191}
192
193#[derive(Clone, Debug, Default, Serialize)]
194pub struct NewReleasesEndpoint {
195    pub(crate) country: Option<String>,
196    pub(crate) limit: Option<u32>,
197    pub(crate) offset: Option<u32>,
198}
199
200impl NewReleasesEndpoint {
201    #[doc = include_str!("../docs/country.md")]
202    pub fn country(mut self, country: impl Into<String>) -> Self {
203        self.country = Some(country.into());
204        self
205    }
206
207    #[doc = include_str!("../docs/limit.md")]
208    pub fn limit(mut self, limit: u32) -> Self {
209        self.limit = Some(limit);
210        self
211    }
212
213    #[doc = include_str!("../docs/offset.md")]
214    pub fn offset(mut self, offset: u32) -> Self {
215        self.offset = Some(offset);
216        self
217    }
218
219    #[doc = include_str!("../docs/send.md")]
220    pub async fn get(self, spotify: &Client<impl AuthFlow>) -> Result<Page<SimplifiedAlbum>> {
221        spotify
222            .get("/browse/new-releases".to_owned(), self)
223            .await
224            .map(|p: PagedAlbums| p.albums)
225    }
226}