#[cfg(test)]
pub mod collection;
use {
serde_json::Value,
tracing::{info, instrument, warn},
};
use crate::{
api::{
content::{push_pagination_params, records::UserFavorites},
requests::{RequestAuth, signed_get, signed_post},
service_state::QobuzApiService,
},
errors::QobuzApiError,
};
async fn modify_favorites(
service: &QobuzApiService,
item_ids: &[i32],
item_type: &str,
endpoint: &str,
log_action: &str,
) -> Result<(), QobuzApiError> {
let token = service.require_auth_token()?;
let ids: String = item_ids
.iter()
.map(ToString::to_string)
.collect::<Vec<_>>()
.join(",");
let mut params = vec![
("item_ids".to_string(), ids),
("item_type".to_string(), item_type.to_string()),
];
let response: Value = signed_post::<Value>(
service.http_client(),
service.base_url(),
endpoint,
&mut params,
&RequestAuth {
app_id: &service.app_id,
app_secret: service.app_secret(),
user_auth_token: token,
},
)
.await?;
if !response.is_object() {
warn!(
endpoint,
item_type, "Favorites modify endpoint returned non-object response"
);
}
info!(
item_type,
count = item_ids.len(),
action = log_action,
"Favorites modified"
);
Ok(())
}
#[instrument(skip(service), fields(item_type, count = item_ids.len()))]
pub async fn add_user_favorites(
service: &QobuzApiService,
item_ids: &[i32],
item_type: &str,
) -> Result<(), QobuzApiError> {
modify_favorites(
service,
item_ids,
item_type,
"/favorite/create",
"Added favorites",
)
.await
}
#[instrument(skip(service), fields(item_type, count = item_ids.len()))]
pub async fn delete_user_favorites(
service: &QobuzApiService,
item_ids: &[i32],
item_type: &str,
) -> Result<(), QobuzApiError> {
modify_favorites(
service,
item_ids,
item_type,
"/favorite/delete",
"Deleted favorites",
)
.await
}
async fn fetch_user_favorites(
service: &QobuzApiService,
params: &mut Vec<(String, String)>,
) -> Result<UserFavorites, QobuzApiError> {
let token = service.require_auth_token()?;
signed_get(
service.http_client(),
service.base_url(),
"/favorite/getUserFavorites",
params,
&RequestAuth {
app_id: &service.app_id,
app_secret: service.app_secret(),
user_auth_token: token,
},
)
.await
}
#[instrument(skip(service), fields(item_type, limit, offset))]
pub async fn get_user_favorites(
service: &QobuzApiService,
item_type: &str,
limit: Option<i32>,
offset: Option<i32>,
) -> Result<UserFavorites, QobuzApiError> {
let mut params: Vec<(String, String)> = vec![("type".to_string(), item_type.to_string())];
push_pagination_params(&mut params, limit, offset);
fetch_user_favorites(service, &mut params).await
}
#[instrument(skip(service))]
pub async fn get_user_favorite_ids(
service: &QobuzApiService,
) -> Result<UserFavorites, QobuzApiError> {
let mut params: Vec<(String, String)> = vec![("type".to_string(), "ids".to_string())];
fetch_user_favorites(service, &mut params).await
}