1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
use std::fmt::Display;
use isocountry::CountryCode;
use itertools::Itertools;
use serde::Deserialize;
use super::chunked_sequence;
use crate::{Client, EpisodeSimplified, Error, Page, Response, Show, ShowSimplified};
/// Endpoint functions relating to shows.
///
/// For all the below endpoints, the market parameter must be specified if the token is not a
/// user's. If the token is a user's and the market parameter is specified, the user's token will
/// take precedence.
#[derive(Debug, Clone, Copy)]
pub struct Shows<'a>(pub &'a Client);
impl Shows<'_> {
/// Get information about a show.
///
/// Either the client must have a refresh token or the `market` parameter must be provided,
/// otherwise this will fail. If both are provided, then the user's market will take
/// precendence.
///
/// [Reference](https://developer.spotify.com/documentation/web-api/reference/shows/get-a-show/).
pub async fn get_show(
self,
id: &str,
market: Option<CountryCode>,
) -> Result<Response<Show>, Error> {
self.0
.send_json(
self.0
.client
.get(endpoint!("/v1/shows/{}", id))
.query(&(market.map(|c| ("market", c.alpha2())),)),
)
.await
}
/// Get several shows.
///
/// Either the client must have a refresh token or the `market` parameter must be provided,
/// otherwise this will fail. If both are provided, then the user's market will take
/// precendence.
///
/// [Reference](https://developer.spotify.com/documentation/web-api/reference/shows/get-several-shows/).
pub async fn get_shows<I: IntoIterator>(
self,
ids: I,
market: Option<CountryCode>,
) -> Result<Response<Vec<ShowSimplified>>, Error>
where
I::Item: Display,
{
#[derive(Deserialize)]
struct Shows {
shows: Vec<ShowSimplified>,
}
chunked_sequence(ids, 50, |mut ids| {
let req = self.0.client.get(endpoint!("/v1/shows")).query(&(
("ids", ids.join(",")),
market.map(|c| ("market", c.alpha2())),
));
async move { Ok(self.0.send_json::<Shows>(req).await?.map(|res| res.shows)) }
})
.await
}
/// Get a show's episodes.
///
/// Either the client must have a refresh token or the `market` parameter must be provided,
/// otherwise this will fail. If both are provided, then the user's market will take
/// precendence.
///
/// [Reference](https://developer.spotify.com/documentation/web-api/reference/shows/get-shows-episodes/).
pub async fn get_show_episodes(
self,
id: &str,
limit: usize,
offset: usize,
market: Option<CountryCode>,
) -> Result<Response<Page<EpisodeSimplified>>, Error> {
self.0
.send_json(
self.0
.client
.get(endpoint!("/v1/shows/{}/episodes", id))
.query(&(
("limit", limit.to_string()),
("offset", offset.to_string()),
market.map(|c| ("market", c.alpha2())),
)),
)
.await
}
}
#[cfg(test)]
mod tests {
use isocountry::CountryCode;
use crate::endpoints::client;
#[tokio::test]
async fn test_get_show() {
let show = client()
.shows()
.get_show("38bS44xjbVVZ3No3ByF1dJ", Some(CountryCode::AUS))
.await
.unwrap()
.data;
assert_eq!(show.name, "Vetenskapsradion Historia");
}
#[tokio::test]
async fn test_get_shows() {
let shows = client()
.shows()
.get_shows(&["5CfCWKI5pZ28U0uOzXkDHe"], None)
.await
.unwrap()
.data;
assert_eq!(shows.len(), 1);
assert_eq!(shows[0].name, "Without Fail");
}
#[tokio::test]
async fn test_get_show_episodes() {
let episodes = client()
.shows()
.get_show_episodes("38bS44xjbVVZ3No3ByF1dJ", 2, 1, None)
.await
.unwrap()
.data;
assert_eq!(episodes.limit, 2);
assert_eq!(episodes.offset, 1);
assert_eq!(episodes.items.len(), 2);
}
}