2021-01-10 19:48:54 +00:00
|
|
|
//! Low-level response data models.
|
2021-01-30 02:06:02 +00:00
|
|
|
//!
|
|
|
|
//! Every response type has the `rate_limit` field, which contains rate limiting
|
|
|
|
//! information. See the documentation of the [`RateLimit`] type for more
|
|
|
|
//! details.
|
2021-01-10 19:48:54 +00:00
|
|
|
|
2021-01-10 16:59:15 +00:00
|
|
|
use std::collections::HashMap;
|
|
|
|
|
2021-09-01 17:14:04 +01:00
|
|
|
use attohttpc::Response;
|
2021-01-30 02:06:02 +00:00
|
|
|
use serde::de::DeserializeOwned;
|
2021-01-09 03:36:14 +00:00
|
|
|
use serde::Deserialize;
|
2021-01-30 02:06:02 +00:00
|
|
|
|
|
|
|
use crate::Error;
|
|
|
|
|
|
|
|
/// Contains rate limiting information.
|
|
|
|
///
|
|
|
|
/// ListenBrainz API rate limiting is described in the [API docs].
|
|
|
|
/// Prefer using the [`RateLimit::reset_in`] field over [`RateLimit::reset`],
|
|
|
|
/// as the former is resilient against clients with incorrect clocks.
|
|
|
|
///
|
|
|
|
/// [API docs]: https://listenbrainz.readthedocs.io/en/production/dev/api/#rate-limiting
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct RateLimit {
|
|
|
|
pub limit: u64,
|
|
|
|
pub remaining: u64,
|
|
|
|
pub reset_in: u64,
|
|
|
|
pub reset: i64,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl RateLimit {
|
|
|
|
/// Extract rate limiting information from the `X-RateLimit-` headers.
|
|
|
|
/// Only returns `Some` if all fields are present and valid.
|
|
|
|
fn from_headers(response: &Response) -> Option<Self> {
|
2021-09-01 17:04:56 +01:00
|
|
|
let headers = response.headers();
|
|
|
|
|
2021-09-01 17:14:04 +01:00
|
|
|
let limit = headers
|
|
|
|
.get("X-RateLimit-Limit")?
|
|
|
|
.to_str()
|
|
|
|
.ok()?
|
|
|
|
.parse()
|
|
|
|
.ok()?;
|
|
|
|
let remaining = headers
|
|
|
|
.get("X-RateLimit-Remaining")?
|
|
|
|
.to_str()
|
|
|
|
.ok()?
|
|
|
|
.parse()
|
|
|
|
.ok()?;
|
|
|
|
let reset_in = headers
|
|
|
|
.get("X-RateLimit-Reset-In")?
|
|
|
|
.to_str()
|
|
|
|
.ok()?
|
|
|
|
.parse()
|
|
|
|
.ok()?;
|
|
|
|
let reset = headers
|
|
|
|
.get("X-RateLimit-Reset")?
|
|
|
|
.to_str()
|
|
|
|
.ok()?
|
|
|
|
.parse()
|
|
|
|
.ok()?;
|
2021-01-30 02:06:02 +00:00
|
|
|
|
|
|
|
Some(Self {
|
|
|
|
limit,
|
|
|
|
remaining,
|
|
|
|
reset_in,
|
|
|
|
reset,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Internal trait for response types.
|
2021-09-01 17:04:56 +01:00
|
|
|
/// Allows converting the response type from an `attohttpc::Response`,
|
2021-01-30 02:06:02 +00:00
|
|
|
/// by deserializing the body into the response type and then
|
|
|
|
/// adding the `rate_limit` field from headers.
|
|
|
|
pub(crate) trait ResponseType: DeserializeOwned {
|
|
|
|
fn from_response(response: Response) -> Result<Self, Error>;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Internal macro for response types.
|
|
|
|
/// Wraps the definition of a response type, adds the `rate_limit` field,
|
|
|
|
/// and implements the `ResponseType` trait.
|
|
|
|
macro_rules! response_type {
|
|
|
|
(
|
|
|
|
$(#[$meta:meta])*
|
|
|
|
pub struct $name:ident {
|
|
|
|
$(pub $field:ident: $field_ty:ty),*
|
|
|
|
$(,)?
|
|
|
|
}
|
|
|
|
) => {
|
|
|
|
$(#[$meta])*
|
|
|
|
pub struct $name {
|
|
|
|
#[serde(skip)]
|
|
|
|
pub rate_limit: Option<RateLimit>,
|
|
|
|
$(pub $field: $field_ty),*
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ResponseType for $name {
|
|
|
|
fn from_response(response: Response) -> Result<Self, Error> {
|
2021-09-01 17:04:56 +01:00
|
|
|
let response = Error::try_from_error_response(response)?;
|
2021-01-30 02:06:02 +00:00
|
|
|
let rate_limit = RateLimit::from_headers(&response);
|
2021-09-01 17:04:56 +01:00
|
|
|
let mut result: Self = response.json()?;
|
2021-01-30 02:06:02 +00:00
|
|
|
result.rate_limit = rate_limit;
|
|
|
|
Ok(result)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-01-09 03:36:14 +00:00
|
|
|
|
|
|
|
// --------- submit-listens
|
|
|
|
|
2021-01-30 02:06:02 +00:00
|
|
|
response_type! {
|
|
|
|
/// Response type for [`Client::submit_listens`](super::Client::submit_listens).
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct SubmitListensResponse {
|
|
|
|
pub status: String,
|
|
|
|
}
|
2021-01-09 03:36:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// --------- validate-token
|
|
|
|
|
2021-01-30 02:06:02 +00:00
|
|
|
response_type! {
|
|
|
|
/// Response type for [`Client::validate_token`](super::Client::validate_token).
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct ValidateTokenResponse {
|
|
|
|
pub code: u16,
|
|
|
|
pub message: String,
|
2021-01-09 03:36:14 +00:00
|
|
|
|
2021-01-30 02:06:02 +00:00
|
|
|
pub valid: bool,
|
|
|
|
pub user_name: Option<String>,
|
|
|
|
}
|
2021-01-09 03:36:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// --------- delete-listen
|
|
|
|
|
2021-01-30 02:06:02 +00:00
|
|
|
response_type! {
|
|
|
|
/// Response type for [`Client::delete_listen`](super::Client::delete_listen).
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct DeleteListenResponse {
|
|
|
|
pub status: String,
|
|
|
|
}
|
2021-01-09 03:36:14 +00:00
|
|
|
}
|
|
|
|
|
2021-01-10 16:59:15 +00:00
|
|
|
// --------- users/{user_list}/recent-listens
|
|
|
|
|
2021-01-30 02:06:02 +00:00
|
|
|
response_type! {
|
|
|
|
/// Response type for [`Client::users_recent_listens`](super::Client::users_recent_listens).
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct UsersRecentListensResponse {
|
|
|
|
pub payload: UsersRecentListensPayload,
|
|
|
|
}
|
2021-01-10 16:59:15 +00:00
|
|
|
}
|
|
|
|
|
2021-01-10 20:38:47 +00:00
|
|
|
/// Type of the [`UsersRecentListensResponse::payload`] field.
|
2021-01-10 16:59:15 +00:00
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct UsersRecentListensPayload {
|
|
|
|
pub count: u64,
|
|
|
|
pub listens: Vec<UsersRecentListensListen>,
|
|
|
|
pub user_list: String,
|
|
|
|
}
|
|
|
|
|
2021-01-10 20:38:47 +00:00
|
|
|
/// Type of the [`UsersRecentListensPayload::listens`] field.
|
2021-01-10 16:59:15 +00:00
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct UsersRecentListensListen {
|
|
|
|
pub user_name: String,
|
|
|
|
pub inserted_at: String,
|
|
|
|
pub listened_at: i64,
|
|
|
|
pub recording_msid: String,
|
|
|
|
pub track_metadata: UsersRecentListensTrackMetadata,
|
|
|
|
}
|
|
|
|
|
2021-01-10 20:38:47 +00:00
|
|
|
/// Type of the [`UsersRecentListensListen::track_metadata`] field.
|
2021-01-10 16:59:15 +00:00
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct UsersRecentListensTrackMetadata {
|
|
|
|
pub artist_name: String,
|
|
|
|
pub track_name: String,
|
|
|
|
pub release_name: Option<String>,
|
|
|
|
pub additional_info: HashMap<String, serde_json::Value>,
|
|
|
|
}
|
|
|
|
|
2021-01-09 03:36:14 +00:00
|
|
|
// --------- user/{user_name}/listen-count
|
|
|
|
|
2021-01-30 02:06:02 +00:00
|
|
|
response_type! {
|
|
|
|
/// Response type for [`Client::user_listen_count`](super::Client::user_listen_count).
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct UserListenCountResponse {
|
|
|
|
pub payload: UserListenCountPayload,
|
|
|
|
}
|
2021-01-14 01:49:08 +00:00
|
|
|
}
|
2021-01-09 03:36:14 +00:00
|
|
|
|
2021-01-14 02:09:17 +00:00
|
|
|
/// Type of the [`UserListenCountResponse::payload`] field.
|
2021-01-14 01:49:08 +00:00
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct UserListenCountPayload {
|
2021-01-09 03:36:14 +00:00
|
|
|
pub count: u64,
|
|
|
|
}
|
|
|
|
|
2021-01-10 16:59:15 +00:00
|
|
|
// -------- user/{user_name}/playing-now
|
|
|
|
|
2021-01-30 02:06:02 +00:00
|
|
|
response_type! {
|
|
|
|
/// Response type for [`Client::user_playing_now`](super::Client::user_playing_now).
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct UserPlayingNowResponse {
|
|
|
|
pub payload: UserPlayingNowPayload,
|
|
|
|
}
|
2021-01-10 16:59:15 +00:00
|
|
|
}
|
|
|
|
|
2021-01-10 20:38:47 +00:00
|
|
|
/// Type of the [`UserPlayingNowResponse::payload`] field.
|
2021-01-10 16:59:15 +00:00
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct UserPlayingNowPayload {
|
|
|
|
pub count: u8,
|
|
|
|
pub user_id: String,
|
2021-01-10 18:31:06 +00:00
|
|
|
pub listens: Vec<UserPlayingNowListen>,
|
|
|
|
}
|
|
|
|
|
2021-01-10 20:38:47 +00:00
|
|
|
/// Type of the [`UserPlayingNowPayload::listens`] field.
|
2021-01-10 18:31:06 +00:00
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct UserPlayingNowListen {
|
|
|
|
pub user_name: String,
|
|
|
|
pub inserted_at: String,
|
|
|
|
pub recording_msid: String,
|
|
|
|
pub track_metadata: UserPlayingNowTrackMetadata,
|
|
|
|
}
|
|
|
|
|
2021-01-10 20:38:47 +00:00
|
|
|
/// Type of the [`UserPlayingNowListen::track_metadata`] field.
|
2021-01-10 18:31:06 +00:00
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct UserPlayingNowTrackMetadata {
|
|
|
|
pub artist_name: String,
|
|
|
|
pub track_name: String,
|
|
|
|
pub release_name: Option<String>,
|
|
|
|
pub additional_info: HashMap<String, serde_json::Value>,
|
2021-01-10 16:59:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// -------- user/{user_name}/listens
|
|
|
|
|
2021-01-30 02:06:02 +00:00
|
|
|
response_type! {
|
|
|
|
/// Response type for [`Client::user_listens`](super::Client::user_listens).
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct UserListensResponse {
|
|
|
|
pub payload: UserListensPayload,
|
|
|
|
}
|
2021-01-10 16:59:15 +00:00
|
|
|
}
|
|
|
|
|
2021-01-10 20:38:47 +00:00
|
|
|
/// Type of the [`UserListensResponse::payload`] field.
|
2021-01-10 16:59:15 +00:00
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct UserListensPayload {
|
|
|
|
pub count: u64,
|
|
|
|
pub latest_listen_ts: i64,
|
|
|
|
pub user_id: String,
|
|
|
|
pub listens: Vec<UserListensListen>,
|
|
|
|
}
|
|
|
|
|
2021-01-10 20:38:47 +00:00
|
|
|
/// Type of the [`UserListensPayload::listens`] field.
|
2021-01-10 16:59:15 +00:00
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct UserListensListen {
|
|
|
|
pub user_name: String,
|
|
|
|
pub inserted_at: String,
|
|
|
|
pub listened_at: i64,
|
|
|
|
pub recording_msid: String,
|
|
|
|
pub track_metadata: UserListensTrackMetadata,
|
|
|
|
}
|
|
|
|
|
2021-01-10 20:38:47 +00:00
|
|
|
/// Type of the [`UserListensListen::track_metadata`] field.
|
2021-01-10 16:59:15 +00:00
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct UserListensTrackMetadata {
|
|
|
|
pub artist_name: String,
|
|
|
|
pub track_name: String,
|
|
|
|
pub release_name: Option<String>,
|
|
|
|
pub additional_info: HashMap<String, serde_json::Value>,
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------- latest-import (GET)
|
|
|
|
|
2021-01-30 02:06:02 +00:00
|
|
|
response_type! {
|
|
|
|
/// Response type for [`Client::get_latest_import`](super::Client::get_latest_import).
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct GetLatestImportResponse {
|
|
|
|
pub latest_import: i64,
|
|
|
|
pub musicbrainz_id: String,
|
|
|
|
}
|
2021-01-10 16:59:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// --------- latest-import (POST)
|
|
|
|
|
2021-01-30 02:06:02 +00:00
|
|
|
response_type! {
|
|
|
|
/// Response type for [`Client::update_latest_import`](super::Client::update_latest_import).
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct UpdateLatestImportResponse {
|
|
|
|
pub status: String,
|
|
|
|
}
|
2021-01-10 16:59:15 +00:00
|
|
|
}
|
|
|
|
|
2021-01-10 20:42:40 +00:00
|
|
|
// --------- stats/sitewide/artists
|
|
|
|
|
2021-01-30 02:06:02 +00:00
|
|
|
response_type! {
|
|
|
|
/// Response type for [`Client::stats_sitewide_artists`](super::Client::stats_sitewide_artists).
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct StatsSitewideArtistsResponse {
|
|
|
|
pub payload: StatsSitewideArtistsPayload,
|
|
|
|
}
|
2021-01-10 20:42:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Type of the [`StatsSitewideArtistsResponse::payload`] field.
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct StatsSitewideArtistsPayload {
|
|
|
|
pub time_ranges: Vec<StatsSitewideArtistsTimeRange>,
|
|
|
|
pub offset: u64,
|
|
|
|
pub count: u64,
|
|
|
|
pub range: String,
|
|
|
|
pub last_updated: i64,
|
|
|
|
pub from_ts: i64,
|
|
|
|
pub to_ts: i64,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Type of the [`StatsSitewideArtistsPayload::time_ranges`] field.
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct StatsSitewideArtistsTimeRange {
|
|
|
|
pub time_range: String,
|
|
|
|
pub artists: Vec<StatsSitewideArtistsArtist>,
|
|
|
|
pub from_ts: i64,
|
|
|
|
pub to_ts: i64,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Type of the [`StatsSitewideArtistsTimeRange::artists`] field.
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct StatsSitewideArtistsArtist {
|
|
|
|
pub artist_mbids: Option<Vec<String>>,
|
|
|
|
pub artist_msid: String,
|
|
|
|
pub artist_name: String,
|
|
|
|
pub listen_count: u64,
|
|
|
|
}
|
|
|
|
|
2021-01-13 12:06:48 +00:00
|
|
|
// --------- stats/user/{user_name}/listening-activity
|
|
|
|
|
2021-01-30 02:06:02 +00:00
|
|
|
response_type! {
|
|
|
|
/// Response type for [`Client::stats_user_listening_activity`](super::Client::stats_user_listening_activity).
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct StatsUserListeningActivityResponse {
|
|
|
|
pub payload: StatsUserListeningActivityPayload,
|
|
|
|
}
|
2021-01-13 12:06:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Type of the [`StatsUserListeningActivityResponse::payload`] field.
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct StatsUserListeningActivityPayload {
|
|
|
|
pub user_id: String,
|
|
|
|
pub listening_activity: Vec<StatsUserListeningActivityListeningActivity>,
|
|
|
|
pub from_ts: i64,
|
|
|
|
pub to_ts: i64,
|
|
|
|
pub last_updated: i64,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Type of the [`StatsUserListeningActivityPayload::listening_activity`] field.
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct StatsUserListeningActivityListeningActivity {
|
|
|
|
pub listen_count: u64,
|
|
|
|
pub from_ts: i64,
|
|
|
|
pub to_ts: i64,
|
|
|
|
pub time_range: String,
|
|
|
|
}
|
|
|
|
|
|
|
|
// --------- stats/user/{user_name}/daily-activity
|
|
|
|
|
2021-01-30 02:06:02 +00:00
|
|
|
response_type! {
|
|
|
|
/// Response type for [`Client::stats_user_daily_activity`](super::Client::stats_user_daily_activity).
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct StatsUserDailyActivityResponse {
|
|
|
|
pub payload: StatsUserDailyActivityPayload,
|
|
|
|
}
|
2021-01-13 12:06:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Type of the [`StatsUserDailyActivityResponse::payload`] field.
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct StatsUserDailyActivityPayload {
|
|
|
|
pub user_id: String,
|
|
|
|
pub daily_activity: StatsUserDailyActivityDailyActivity,
|
|
|
|
pub from_ts: i64,
|
|
|
|
pub to_ts: i64,
|
2021-01-13 12:46:29 +00:00
|
|
|
pub last_updated: i64,
|
2021-01-13 12:06:48 +00:00
|
|
|
pub stats_range: String,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Type of the [`StatsUserDailyActivityPayload::daily_activity`] field.
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct StatsUserDailyActivityDailyActivity {
|
|
|
|
pub days: HashMap<String, Vec<StatsUserDailyActivityHour>>,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Type of the [`StatsUserDailyActivityDailyActivity::days`] field.
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct StatsUserDailyActivityHour {
|
|
|
|
pub hour: u8,
|
|
|
|
pub listen_count: u64,
|
|
|
|
}
|
|
|
|
|
2021-01-13 12:46:29 +00:00
|
|
|
// --------- stats/user/{user_name}/recordings
|
|
|
|
|
2021-01-30 02:06:02 +00:00
|
|
|
response_type! {
|
|
|
|
/// Response type of [`Client::stats_user_recordings`](super::Client::stats_user_recordings).
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct StatsUserRecordingsResponse {
|
|
|
|
pub payload: StatsUserRecordingsPayload,
|
|
|
|
}
|
2021-01-13 12:46:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Type of the [`StatsUserRecordingsResponse::payload`] field.
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct StatsUserRecordingsPayload {
|
|
|
|
pub recordings: Vec<StatsUserRecordingsRecording>,
|
|
|
|
pub count: u64,
|
|
|
|
pub total_recording_count: u64,
|
|
|
|
pub user_id: String,
|
|
|
|
pub from_ts: i64,
|
|
|
|
pub to_ts: i64,
|
|
|
|
pub last_updated: i64,
|
|
|
|
pub range: String,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Type of the [`StatsUserRecordingsPayload::recordings`] field.
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct StatsUserRecordingsRecording {
|
|
|
|
pub artist_mbids: Option<Vec<String>>,
|
|
|
|
pub artist_msid: Option<String>,
|
|
|
|
pub artist_name: String,
|
|
|
|
pub listen_count: u64,
|
|
|
|
pub recording_mbid: Option<String>,
|
|
|
|
pub recording_msid: Option<String>,
|
|
|
|
pub release_mbid: Option<String>,
|
|
|
|
pub release_msid: Option<String>,
|
|
|
|
pub release_name: Option<String>,
|
|
|
|
pub track_name: Option<String>,
|
|
|
|
}
|
|
|
|
|
2021-01-13 13:02:23 +00:00
|
|
|
// --------- stats/user/{user_name}/artist-map
|
|
|
|
|
2021-01-30 02:06:02 +00:00
|
|
|
response_type! {
|
|
|
|
/// Response type of [`Client::stats_user_artist_map`](super::Client::stats_user_artist_map).
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct StatsUserArtistMapResponse {
|
|
|
|
pub payload: StatsUserArtistMapPayload,
|
|
|
|
}
|
2021-01-13 13:02:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Type of the [`StatsUserArtistMapResponse::payload`] field.
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct StatsUserArtistMapPayload {
|
|
|
|
pub artist_map: Vec<StatsUserArtistMapCountry>,
|
|
|
|
pub user_id: String,
|
|
|
|
pub from_ts: i64,
|
|
|
|
pub to_ts: i64,
|
|
|
|
pub last_updated: i64,
|
|
|
|
pub range: String,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Type of the [`StatsUserArtistMapPayload::artist_map`] field.
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct StatsUserArtistMapCountry {
|
|
|
|
pub country: String,
|
|
|
|
pub artist_count: u64,
|
|
|
|
}
|
|
|
|
|
2021-01-13 13:09:34 +00:00
|
|
|
// --------- stats/user/{user_name}/releases
|
|
|
|
|
2021-01-30 02:06:02 +00:00
|
|
|
response_type! {
|
|
|
|
/// Response type for [`Client::stats_user_releases`](super::Client::stats_user_releases).
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct StatsUserReleasesResponse {
|
|
|
|
pub payload: StatsUserReleasesPayload,
|
|
|
|
}
|
2021-01-13 13:09:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Type of the [`StatsUserReleasesResponse::payload`] field.
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct StatsUserReleasesPayload {
|
|
|
|
pub releases: Vec<StatsUserReleasesRelease>,
|
|
|
|
pub count: u64,
|
|
|
|
pub total_release_count: u64,
|
|
|
|
pub user_id: String,
|
|
|
|
pub from_ts: i64,
|
|
|
|
pub to_ts: i64,
|
|
|
|
pub last_updated: i64,
|
|
|
|
pub range: String,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Type of the [`StatsUserReleasesPayload::releases`] field.
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct StatsUserReleasesRelease {
|
|
|
|
pub artist_mbids: Option<Vec<String>>,
|
|
|
|
pub artist_msid: Option<String>,
|
|
|
|
pub artist_name: String,
|
|
|
|
pub listen_count: u64,
|
|
|
|
pub release_mbid: Option<String>,
|
|
|
|
pub release_msid: Option<String>,
|
|
|
|
pub release_name: String,
|
|
|
|
}
|
|
|
|
|
2021-01-13 13:15:32 +00:00
|
|
|
// --------- stats/user/{user_name}/artists
|
|
|
|
|
2021-01-30 02:06:02 +00:00
|
|
|
response_type! {
|
|
|
|
/// Response type of [`Client::stats_user_artists`](super::Client::stats_user_artists).
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct StatsUserArtistsResponse {
|
|
|
|
pub payload: StatsUserArtistsPayload,
|
|
|
|
}
|
2021-01-13 13:15:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Type of the [`StatsUserArtistsResponse::payload`] field.
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct StatsUserArtistsPayload {
|
|
|
|
pub artists: Vec<StatsUserArtistsArtist>,
|
|
|
|
pub count: u64,
|
|
|
|
pub total_artist_count: u64,
|
|
|
|
pub user_id: String,
|
|
|
|
pub from_ts: i64,
|
|
|
|
pub to_ts: i64,
|
|
|
|
pub last_updated: i64,
|
|
|
|
pub range: String,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Type of the [`StatsUserArtistsPayload::artists`] field.
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct StatsUserArtistsArtist {
|
|
|
|
pub artist_mbids: Option<Vec<String>>,
|
|
|
|
pub artist_msid: Option<String>,
|
|
|
|
pub artist_name: String,
|
|
|
|
pub listen_count: u64,
|
|
|
|
}
|
|
|
|
|
2021-01-09 03:36:14 +00:00
|
|
|
// --------- status/get-dump-info
|
|
|
|
|
2021-01-30 02:06:02 +00:00
|
|
|
response_type! {
|
|
|
|
/// Response type for [`Client::status_get_dump_info`](super::Client::status_get_dump_info).
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
|
|
pub struct StatusGetDumpInfoResponse {
|
|
|
|
pub code: u16,
|
|
|
|
pub message: String,
|
2021-01-09 03:36:14 +00:00
|
|
|
|
2021-01-30 02:06:02 +00:00
|
|
|
pub id: i64,
|
|
|
|
pub timestamp: String,
|
|
|
|
}
|
2021-01-09 03:36:14 +00:00
|
|
|
}
|