use crate::*;
pub async fn user_saved_albums(
token: &AccessToken,
ids: &[&str],
) -> Result<Vec<bool>, EndpointError<Error>> {
if ids.is_empty() {
return Ok(Vec::new());
}
Ok(request!(
token,
GET "/v1/me/albums/contains",
query_params = {"ids": ids.join(",")},
ret = Vec<bool>
))
}
pub async fn user_saved_tracks(
token: &AccessToken,
ids: &[&str],
) -> Result<Vec<bool>, EndpointError<Error>> {
if ids.is_empty() {
return Ok(Vec::new());
}
Ok(request!(
token,
GET "/v1/me/tracks/contains",
query_params = {"ids": ids.join(",")},
ret = Vec<bool>
))
}
pub async fn get_saved_albums(
token: &AccessToken,
limit: usize,
offset: usize,
market: Option<Market>,
) -> Result<Page<SavedAlbum>, EndpointError<Error>> {
Ok(request!(
token,
GET "/v1/me/albums",
query_params = {"limit": limit.to_string(), "offset": offset.to_string()},
optional_query_params = {"market": market.map(|m| m.as_str())},
ret = Page<SavedAlbum>
))
}
pub async fn get_saved_tracks(
token: &AccessToken,
limit: usize,
offset: usize,
market: Option<Market>,
) -> Result<Page<SavedTrack>, EndpointError<Error>> {
Ok(request!(
token,
GET "/v1/me/tracks",
query_params = {"limit": limit.to_string(), "offset": offset.to_string()},
optional_query_params = {"market": market.map(|m| m.as_str())},
ret = Page<SavedTrack>
))
}
pub async fn unsave_albums(token: &AccessToken, ids: &[&str]) -> Result<(), EndpointError<Error>> {
if ids.is_empty() {
return Ok(());
}
request!(
token,
DELETE "/v1/me/albums",
query_params = {"ids": ids.join(",")},
body = "{}"
);
Ok(())
}
pub async fn unsave_tracks(token: &AccessToken, ids: &[&str]) -> Result<(), EndpointError<Error>> {
if ids.is_empty() {
return Ok(());
}
request!(
token,
DELETE "/v1/me/tracks",
query_params = {"ids": ids.join(",")},
body = "{}"
);
Ok(())
}
pub async fn save_albums(token: &AccessToken, ids: &[&str]) -> Result<(), EndpointError<Error>> {
if ids.is_empty() {
return Ok(());
}
request!(
token,
PUT "/v1/me/albums",
query_params = {"ids": ids.join(",")},
body = "{}"
);
Ok(())
}
pub async fn save_tracks(token: &AccessToken, ids: &[&str]) -> Result<(), EndpointError<Error>> {
if ids.is_empty() {
return Ok(());
}
request!(
token,
PUT "/v1/me/tracks",
query_params = {"ids": ids.join(",")},
body = "{}"
);
Ok(())
}
#[cfg(test)]
mod tests {
use crate::endpoints::token;
use crate::*;
#[tokio::test]
async fn test_save_albums() {
let token = token().await;
let albums = &[
"0aEL0zQ4XLuxQP0j7sLlS1",
"0FZK97MXMm5mUQ8mtudjuK",
"4ocal2JegUDVQdP6KN1roI",
];
let split = 2;
let (saved_albums, unsaved_albums) = albums.split_at(split);
let old = user_saved_albums(&token, albums).await.unwrap();
save_albums(&token, saved_albums).await.unwrap();
unsave_albums(&token, unsaved_albums).await.unwrap();
let check = user_saved_albums(&token, albums).await.unwrap();
let (save_check, unsave_check) = check.split_at(split);
assert!(save_check.into_iter().all(|&saved| saved));
assert!(unsave_check.into_iter().all(|&saved| !saved));
let saved = get_saved_albums(&token, 50, 0, None).await.unwrap();
if saved.total <= 50 {
for saved_album in saved_albums {
assert!(saved
.items
.iter()
.any(|album| album.album.id == *saved_album));
}
for unsaved_album in unsaved_albums {
assert!(saved
.items
.iter()
.all(|album| album.album.id != *unsaved_album));
}
}
let mut old_saved = Vec::with_capacity(albums.len());
let mut old_unsaved = Vec::with_capacity(albums.len());
for i in 0..albums.len() {
if old[i] {
&mut old_saved
} else {
&mut old_unsaved
}
.push(albums[i]);
}
save_albums(&token, &old_saved).await.unwrap();
unsave_albums(&token, &old_unsaved).await.unwrap();
}
#[tokio::test]
async fn test_save_tracks() {
let token = token().await;
let tracks = &["4QlzkaRHtU8gAdwqjWmO8n", "77hzctaLvLRLAh71LwNPE3"];
let split = 1;
let (saved_tracks, unsaved_tracks) = tracks.split_at(split);
let old = user_saved_tracks(&token, tracks).await.unwrap();
save_tracks(&token, saved_tracks).await.unwrap();
unsave_tracks(&token, unsaved_tracks).await.unwrap();
let check = user_saved_tracks(&token, tracks).await.unwrap();
let (save_check, unsave_check) = check.split_at(split);
assert!(save_check.into_iter().all(|&saved| saved));
assert!(unsave_check.into_iter().all(|&saved| !saved));
let saved = get_saved_tracks(&token, 50, 0, None).await.unwrap();
if saved.total <= 50 {
for saved_track in saved_tracks {
assert!(saved
.items
.iter()
.any(|track| track.track.id == *saved_track));
}
for unsaved_track in unsaved_tracks {
assert!(saved
.items
.iter()
.all(|track| track.track.id != *unsaved_track));
}
}
let mut old_saved = Vec::with_capacity(tracks.len());
let mut old_unsaved = Vec::with_capacity(tracks.len());
for i in 0..tracks.len() {
if old[i] {
&mut old_saved
} else {
&mut old_unsaved
}
.push(tracks[i]);
}
save_tracks(&token, &old_saved).await.unwrap();
unsave_tracks(&token, &old_unsaved).await.unwrap();
}
}