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 #[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}