spotify_rs/endpoint/
show.rs

1use serde::Serialize;
2
3use crate::{
4    auth::{AuthFlow, Authorised},
5    body_list,
6    error::Result,
7    model::{
8        show::{
9            Episode, Episodes, SavedEpisode, SavedShow, Show, Shows, SimplifiedEpisode,
10            SimplifiedShow,
11        },
12        Page,
13    },
14    query_list, Nil,
15};
16
17use super::{Client, Endpoint};
18
19impl Endpoint for ShowEndpoint {}
20impl Endpoint for ShowsEndpoint {}
21impl Endpoint for ShowEpisodesEndpoint {}
22impl Endpoint for SavedShowsEndpoint {}
23impl Endpoint for EpisodeEndpoint {}
24impl Endpoint for EpisodesEndpoint {}
25impl Endpoint for SavedEpisodesEndpoint {}
26
27pub fn show(id: impl Into<String>) -> ShowEndpoint {
28    ShowEndpoint {
29        id: id.into(),
30        market: None,
31    }
32}
33
34pub fn shows<T: AsRef<str>>(ids: &[T]) -> ShowsEndpoint {
35    ShowsEndpoint {
36        ids: query_list(ids),
37        market: None,
38    }
39}
40
41pub fn show_episodes(show_id: impl Into<String>) -> ShowEpisodesEndpoint {
42    ShowEpisodesEndpoint {
43        show_id: show_id.into(),
44        ..Default::default()
45    }
46}
47
48pub fn saved_shows() -> SavedShowsEndpoint {
49    SavedShowsEndpoint::default()
50}
51
52pub async fn save_shows<T: AsRef<str>>(
53    ids: &[T],
54    spotify: &Client<impl AuthFlow + Authorised>,
55) -> Result<Nil> {
56    spotify
57        .put("/me/shows".to_owned(), body_list("ids", ids))
58        .await
59}
60
61pub async fn remove_saved_shows<T: AsRef<str>>(
62    ids: &[T],
63    spotify: &Client<impl AuthFlow + Authorised>,
64) -> Result<Nil> {
65    spotify
66        .delete("/me/shows".to_owned(), body_list("ids", ids))
67        .await
68}
69
70pub async fn check_saved_shows<T: AsRef<str>>(
71    ids: &[T],
72    spotify: &Client<impl AuthFlow + Authorised>,
73) -> Result<Vec<bool>> {
74    spotify
75        .get("/me/shows/contains".to_owned(), [("ids", query_list(ids))])
76        .await
77}
78
79pub fn episode(id: impl Into<String>) -> EpisodeEndpoint {
80    EpisodeEndpoint {
81        id: id.into(),
82        market: None,
83    }
84}
85
86pub fn episodes<T: AsRef<str>>(ids: &[T]) -> EpisodesEndpoint {
87    EpisodesEndpoint {
88        ids: query_list(ids),
89        market: None,
90    }
91}
92
93pub fn saved_episodes() -> SavedEpisodesEndpoint {
94    SavedEpisodesEndpoint::default()
95}
96
97pub async fn save_episodes<T: AsRef<str>>(
98    ids: &[T],
99    spotify: &Client<impl AuthFlow + Authorised>,
100) -> Result<Nil> {
101    spotify
102        .put("/me/episodes".to_owned(), body_list("ids", ids))
103        .await
104}
105
106pub async fn remove_saved_episodes<T: AsRef<str>>(
107    ids: &[T],
108    spotify: &Client<impl AuthFlow + Authorised>,
109) -> Result<Nil> {
110    spotify
111        .delete("/me/episodes".to_owned(), body_list("ids", ids))
112        .await
113}
114
115pub async fn check_saved_episodes<T: AsRef<str>>(
116    ids: &[T],
117    spotify: &Client<impl AuthFlow + Authorised>,
118) -> Result<Vec<bool>> {
119    spotify
120        .get::<(), _>(
121            format!("/me/episodes/contains?ids={}", query_list(ids)),
122            None,
123        )
124        .await
125}
126
127#[derive(Clone, Debug, Default, Serialize)]
128pub struct ShowEndpoint {
129    #[serde(skip)]
130    pub(crate) id: String,
131    pub(crate) market: Option<String>,
132}
133
134impl ShowEndpoint {
135    #[doc = include_str!("../docs/market.md")]
136    pub fn market(mut self, market: impl Into<String>) -> Self {
137        self.market = Some(market.into());
138        self
139    }
140
141    #[doc = include_str!("../docs/send.md")]
142    pub async fn get(self, spotify: &Client<impl AuthFlow>) -> Result<Show> {
143        spotify.get(format!("/shows/{}", self.id), self).await
144    }
145}
146
147#[derive(Clone, Debug, Default, Serialize)]
148pub struct ShowsEndpoint {
149    pub(crate) ids: String,
150    pub(crate) market: Option<String>,
151}
152
153impl ShowsEndpoint {
154    #[doc = include_str!("../docs/market.md")]
155    pub fn market(mut self, market: impl Into<String>) -> Self {
156        self.market = Some(market.into());
157        self
158    }
159
160    // This doesn't flatten the result into a Vec<SimplifiedShow> because the user might want to
161    // know that some of the shows they want return null.
162    #[doc = include_str!("../docs/send.md")]
163    pub async fn get(self, spotify: &Client<impl AuthFlow>) -> Result<Vec<Option<SimplifiedShow>>> {
164        spotify
165            .get("/shows/".to_owned(), self)
166            .await
167            .map(|s: Shows| s.shows)
168    }
169}
170
171#[derive(Clone, Debug, Default, Serialize)]
172pub struct ShowEpisodesEndpoint {
173    #[serde(skip)]
174    pub(crate) show_id: String,
175    pub(crate) market: Option<String>,
176    pub(crate) limit: Option<u32>,
177    pub(crate) offset: Option<u32>,
178}
179
180impl ShowEpisodesEndpoint {
181    #[doc = include_str!("../docs/market.md")]
182    pub fn market(mut self, market: impl Into<String>) -> Self {
183        self.market = Some(market.into());
184        self
185    }
186
187    #[doc = include_str!("../docs/limit.md")]
188    pub fn limit(mut self, limit: u32) -> Self {
189        self.limit = Some(limit);
190        self
191    }
192
193    #[doc = include_str!("../docs/offset.md")]
194    pub fn offset(mut self, offset: u32) -> Self {
195        self.offset = Some(offset);
196        self
197    }
198
199    #[doc = include_str!("../docs/send.md")]
200    pub async fn get(self, spotify: &Client<impl AuthFlow>) -> Result<Page<SimplifiedEpisode>> {
201        spotify
202            .get(format!("/shows/{}/episodes", self.show_id), self)
203            .await
204    }
205}
206
207#[derive(Clone, Debug, Default, Serialize)]
208pub struct SavedShowsEndpoint {
209    pub(crate) limit: Option<u32>,
210    pub(crate) offset: Option<u32>,
211}
212
213impl SavedShowsEndpoint {
214    #[doc = include_str!("../docs/limit.md")]
215    pub fn limit(mut self, limit: u32) -> Self {
216        self.limit = Some(limit);
217        self
218    }
219
220    #[doc = include_str!("../docs/offset.md")]
221    pub fn offset(mut self, offset: u32) -> Self {
222        self.offset = Some(offset);
223        self
224    }
225
226    #[doc = include_str!("../docs/send.md")]
227    pub async fn get(
228        self,
229        spotify: &Client<impl AuthFlow + Authorised>,
230    ) -> Result<Page<SavedShow>> {
231        spotify.get("/me/shows".to_owned(), self).await
232    }
233}
234
235#[derive(Clone, Debug, Default, Serialize)]
236pub struct EpisodeEndpoint {
237    #[serde(skip)]
238    pub(crate) id: String,
239    pub(crate) market: Option<String>,
240}
241
242impl EpisodeEndpoint {
243    #[doc = include_str!("../docs/market.md")]
244    pub fn market(mut self, market: impl Into<String>) -> Self {
245        self.market = Some(market.into());
246        self
247    }
248
249    #[doc = include_str!("../docs/send.md")]
250    pub async fn get(self, spotify: &Client<impl AuthFlow>) -> Result<Episode> {
251        spotify.get(format!("/episodes/{}", self.id), self).await
252    }
253}
254
255#[derive(Clone, Debug, Default, Serialize)]
256pub struct EpisodesEndpoint {
257    pub(crate) ids: String,
258    pub(crate) market: Option<String>,
259}
260
261impl EpisodesEndpoint {
262    #[doc = include_str!("../docs/market.md")]
263    pub fn market(mut self, market: impl Into<String>) -> Self {
264        self.market = Some(market.into());
265        self
266    }
267
268    #[doc = include_str!("../docs/send.md")]
269    pub async fn get(self, spotify: &Client<impl AuthFlow>) -> Result<Vec<Option<Episode>>> {
270        spotify
271            .get("/episodes/".to_owned(), self)
272            .await
273            .map(|e: Episodes| e.episodes)
274    }
275}
276
277#[derive(Clone, Debug, Default, Serialize)]
278pub struct SavedEpisodesEndpoint {
279    pub(crate) market: Option<String>,
280    pub(crate) limit: Option<u32>,
281    pub(crate) offset: Option<u32>,
282}
283
284impl SavedEpisodesEndpoint {
285    #[doc = include_str!("../docs/market.md")]
286    pub fn market(mut self, market: impl Into<String>) -> Self {
287        self.market = Some(market.into());
288        self
289    }
290
291    #[doc = include_str!("../docs/limit.md")]
292    pub fn limit(mut self, limit: u32) -> Self {
293        self.limit = Some(limit);
294        self
295    }
296
297    #[doc = include_str!("../docs/offset.md")]
298    pub fn offset(mut self, offset: u32) -> Self {
299        self.offset = Some(offset);
300        self
301    }
302
303    #[doc = include_str!("../docs/send.md")]
304    pub async fn get(
305        self,
306        spotify: &Client<impl AuthFlow + Authorised>,
307    ) -> Result<Page<SavedEpisode>> {
308        spotify.get("/me/episodes".to_owned(), self).await
309    }
310}