1use serde::Serialize;
2
3use crate::{
4 auth::{AuthFlow, Authorised},
5 error::Result,
6 model::{
7 audiobook::{
8 Audiobook, Audiobooks, Chapter, Chapters, SimplifiedAudiobook, SimplifiedChapter,
9 },
10 Page,
11 },
12 query_list, Nil,
13};
14
15use super::{Client, Endpoint};
16
17impl Endpoint for AudiobookEndpoint {}
18impl Endpoint for AudiobooksEndpoint {}
19impl Endpoint for AudiobookChaptersEndpoint {}
20impl Endpoint for SavedAudiobooksEndpoint {}
21impl Endpoint for ChapterEndpoint {}
22impl Endpoint for ChaptersEndpoint {}
23
24#[doc = include_str!("../docs/client_creds_error.md")]
25pub fn audiobook(id: impl Into<String>) -> AudiobookEndpoint {
26 AudiobookEndpoint {
27 id: id.into(),
28 market: None,
29 }
30}
31
32#[doc = include_str!("../docs/client_creds_error.md")]
33pub fn audiobooks<T: AsRef<str>>(ids: &[T]) -> AudiobooksEndpoint {
34 AudiobooksEndpoint {
35 ids: query_list(ids),
36 market: None,
37 }
38}
39
40#[doc = include_str!("../docs/client_creds_error.md")]
41pub fn audiobook_chapters(audiobook_id: impl Into<String>) -> AudiobookChaptersEndpoint {
42 AudiobookChaptersEndpoint {
43 id: audiobook_id.into(),
44 ..Default::default()
45 }
46}
47
48pub fn saved_audiobooks() -> SavedAudiobooksEndpoint {
49 SavedAudiobooksEndpoint::default()
50}
51
52pub async fn save_audiobooks<T: AsRef<str>>(
53 ids: &[T],
54 spotify: &Client<impl AuthFlow + Authorised>,
55) -> Result<Nil> {
56 spotify
57 .put::<(), _>(format!("/me/audiobooks?ids={}", query_list(ids)), None)
58 .await
59}
60
61pub async fn remove_saved_audiobooks<T: AsRef<str>>(
62 ids: &[T],
63 spotify: &Client<impl AuthFlow + Authorised>,
64) -> Result<Nil> {
65 spotify
66 .delete::<(), _>(format!("/me/audiobooks?ids={}", query_list(ids)), None)
67 .await
68}
69
70pub async fn check_saved_audiobooks<T: AsRef<str>>(
71 ids: &[T],
72 spotify: &Client<impl AuthFlow + Authorised>,
73) -> Result<Vec<bool>> {
74 spotify
75 .get(
76 "/me/audiobooks/contains".to_owned(),
77 [("ids", query_list(ids))],
78 )
79 .await
80}
81
82#[doc = include_str!("../docs/client_creds_error.md")]
83pub fn chapter(id: impl Into<String>) -> ChapterEndpoint {
84 ChapterEndpoint {
85 id: id.into(),
86 market: None,
87 }
88}
89
90#[doc = include_str!("../docs/client_creds_error.md")]
91pub fn chapters<T: AsRef<str>>(ids: &[T]) -> ChaptersEndpoint {
92 ChaptersEndpoint {
93 ids: query_list(ids),
94 market: None,
95 }
96}
97
98#[derive(Clone, Debug, Default, Serialize)]
99pub struct AudiobookEndpoint {
100 #[serde(skip)]
101 pub(crate) id: String,
102 pub(crate) market: Option<String>,
103}
104
105impl AudiobookEndpoint {
106 #[doc = include_str!("../docs/market.md")]
107 pub fn market(mut self, market: impl Into<String>) -> Self {
108 self.market = Some(market.into());
109 self
110 }
111
112 #[doc = include_str!("../docs/send.md")]
113 pub async fn get(self, spotify: &Client<impl AuthFlow>) -> Result<Audiobook> {
114 spotify.get(format!("/audiobooks/{}", self.id), self).await
115 }
116}
117
118#[derive(Clone, Debug, Default, Serialize)]
119pub struct AudiobooksEndpoint {
120 pub(crate) ids: String,
121 pub(crate) market: Option<String>,
122}
123
124impl AudiobooksEndpoint {
125 #[doc = include_str!("../docs/market.md")]
126 pub fn market(mut self, market: impl Into<String>) -> Self {
127 self.market = Some(market.into());
128 self
129 }
130
131 #[doc = include_str!("../docs/send.md")]
132 pub async fn get(self, spotify: &Client<impl AuthFlow>) -> Result<Vec<Option<Audiobook>>> {
133 spotify
134 .get("/audiobooks".to_owned(), self)
135 .await
136 .map(|a: Audiobooks| a.audiobooks)
137 }
138}
139
140#[derive(Clone, Debug, Default, Serialize)]
141pub struct AudiobookChaptersEndpoint {
142 #[serde(skip)]
143 pub(crate) id: String,
144 pub(crate) market: Option<String>,
145 pub(crate) limit: Option<u32>,
146 pub(crate) offset: Option<u32>,
147}
148
149impl AudiobookChaptersEndpoint {
150 #[doc = include_str!("../docs/market.md")]
151 pub fn market(mut self, market: impl Into<String>) -> Self {
152 self.market = Some(market.into());
153 self
154 }
155
156 #[doc = include_str!("../docs/limit.md")]
157 pub fn limit(mut self, limit: u32) -> Self {
158 self.limit = Some(limit);
159 self
160 }
161
162 #[doc = include_str!("../docs/offset.md")]
163 pub fn offset(mut self, offset: u32) -> Self {
164 self.offset = Some(offset);
165 self
166 }
167
168 #[doc = include_str!("../docs/send.md")]
169 pub async fn get(self, spotify: &Client<impl AuthFlow>) -> Result<Page<SimplifiedChapter>> {
170 spotify
171 .get(format!("/audiobooks/{}/chapters", self.id), self)
172 .await
173 }
174}
175
176#[derive(Clone, Debug, Default, Serialize)]
177pub struct SavedAudiobooksEndpoint {
178 pub(crate) limit: Option<u32>,
179 pub(crate) offset: Option<u32>,
180}
181
182impl SavedAudiobooksEndpoint {
183 #[doc = include_str!("../docs/limit.md")]
184 pub fn limit(mut self, limit: u32) -> Self {
185 self.limit = Some(limit);
186 self
187 }
188
189 #[doc = include_str!("../docs/offset.md")]
190 pub fn offset(mut self, offset: u32) -> Self {
191 self.offset = Some(offset);
192 self
193 }
194
195 #[doc = include_str!("../docs/send.md")]
196 pub async fn get(
197 self,
198 spotify: &Client<impl AuthFlow + Authorised>,
199 ) -> Result<Page<SimplifiedAudiobook>> {
200 spotify.get("/me/audiobooks".to_owned(), self).await.map(
203 |p: Page<Option<SimplifiedAudiobook>>| Page {
204 href: p.href,
205 limit: p.limit,
206 next: p.next,
207 offset: p.offset,
208 previous: p.previous,
209 total: p.total,
210 items: p.items.into_iter().flatten().collect(),
211 },
212 )
213 }
214}
215
216#[derive(Clone, Debug, Default, Serialize)]
217pub struct ChapterEndpoint {
218 #[serde(skip)]
219 pub(crate) id: String,
220 pub(crate) market: Option<String>,
221}
222
223impl ChapterEndpoint {
224 #[doc = include_str!("../docs/market.md")]
225 pub fn market(mut self, market: impl Into<String>) -> Self {
226 self.market = Some(market.into());
227 self
228 }
229
230 #[doc = include_str!("../docs/send.md")]
231 pub async fn get(self, spotify: &Client<impl AuthFlow>) -> Result<Chapter> {
232 spotify.get(format!("/chapters/{}", self.id), self).await
233 }
234}
235
236#[derive(Clone, Debug, Default, Serialize)]
237pub struct ChaptersEndpoint {
238 pub(crate) ids: String,
239 pub(crate) market: Option<String>,
240}
241
242impl ChaptersEndpoint {
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<Vec<Option<Chapter>>> {
251 spotify
252 .get("/chapters/".to_owned(), self)
253 .await
254 .map(|c: Chapters| c.chapters)
255 }
256}