From 0d8dadd4574e34a023904261c0319449667399a7 Mon Sep 17 00:00:00 2001 From: RustyNova Date: Thu, 4 Apr 2024 11:12:24 +0200 Subject: [PATCH 01/13] refactor: Moved response into module folder --- src/raw/{response.rs => response/mod.rs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/raw/{response.rs => response/mod.rs} (100%) diff --git a/src/raw/response.rs b/src/raw/response/mod.rs similarity index 100% rename from src/raw/response.rs rename to src/raw/response/mod.rs From 461cf08a9e746ce11ea1814b3ff5619d577d9bf2 Mon Sep 17 00:00:00 2001 From: RustyNova Date: Thu, 4 Apr 2024 11:44:48 +0200 Subject: [PATCH 02/13] refactor: Moved Core API Responses --- src/raw/response/core/mod.rs | 277 +++++++++++++++++++++++++++++++++++ src/raw/response/mod.rs | 249 ++----------------------------- 2 files changed, 290 insertions(+), 236 deletions(-) create mode 100644 src/raw/response/core/mod.rs diff --git a/src/raw/response/core/mod.rs b/src/raw/response/core/mod.rs new file mode 100644 index 0000000..cd64f69 --- /dev/null +++ b/src/raw/response/core/mod.rs @@ -0,0 +1,277 @@ +use std::collections::HashMap; + +use serde::Serialize; + +use super::response_type; +use crate::raw::jspf; +use crate::raw::response::Deserialize; + +// --------- GET /1/search/users/ +// https://listenbrainz.readthedocs.io/en/latest/users/api/core.html#get--1-search-users- + +// TODO + +// --------- POST /1/submit-listens +// https://listenbrainz.readthedocs.io/en/latest/users/api/core.html#post--1-submit-listens + +response_type! { + /// Response type for [`Client::submit_listens`](super::Client::submit_listens). + #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] + pub struct SubmitListensResponse { + pub status: String, + } +} + +// --------- GET /1/user/(user_name)/listens +// https://listenbrainz.readthedocs.io/en/latest/users/api/core.html#get--1-user-(user_name)-listens + +response_type! { + /// Response type for [`Client::user_listens`](super::Client::user_listens). + #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] + pub struct UserListensResponse { + pub payload: UserListensPayload, + } +} + +/// Type of the [`UserListensResponse::payload`] field. +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] +pub struct UserListensPayload { + pub count: u64, + pub latest_listen_ts: i64, + pub oldest_listen_ts: i64, + pub user_id: String, + pub listens: Vec, +} + +/// Type of the [`UserListensPayload::listens`] field. +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] +pub struct UserListensListen { + pub user_name: String, + pub inserted_at: i64, + pub listened_at: i64, + pub recording_msid: String, + pub track_metadata: UserListensTrackMetadata, +} + +/// Type of the [`UserListensListen::track_metadata`] field. +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] +pub struct UserListensTrackMetadata { + pub artist_name: String, + pub track_name: String, + pub release_name: Option, + pub additional_info: HashMap, + pub mbid_mapping: Option, +} + +/// Type of the [`UserListensTrackMetadata::mbid_mapping`] field. +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] +pub struct UserListensMBIDMapping { + pub artist_mbids: Option>, + pub artists: Option>, + pub recording_mbid: String, + pub recording_name: Option, + pub caa_id: Option, + pub caa_release_mbid: Option, + pub release_mbid: Option, +} + +/// Type of the [`UserListensMBIDMapping::artists`] field. +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] +pub struct UserListensMappingArtist { + pub artist_mbid: String, + pub artist_credit_name: String, + pub join_phrase: String, +} + +// --------- GET /1/user/(user_name)/listen-count +// https://listenbrainz.readthedocs.io/en/latest/users/api/core.html#get--1-user-(user_name)-listen-count + +response_type! { + /// Response type for [`Client::user_listen_count`](super::Client::user_listen_count). + #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] + pub struct UserListenCountResponse { + pub payload: UserListenCountPayload, + } +} + +/// Type of the [`UserListenCountResponse::payload`] field. +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] +pub struct UserListenCountPayload { + pub count: u64, +} + +// --------- GET /1/user/(user_name)/playing-now +// https://listenbrainz.readthedocs.io/en/latest/users/api/core.html#get--1-user-(user_name)-playing-now + +response_type! { + /// Response type for [`Client::user_playing_now`](super::Client::user_playing_now). + #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] + pub struct UserPlayingNowResponse { + pub payload: UserPlayingNowPayload, + } +} + +/// Type of the [`UserPlayingNowResponse::payload`] field. +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] +pub struct UserPlayingNowPayload { + pub count: u8, + pub user_id: String, + pub listens: Vec, + pub playing_now: bool, +} + +/// Type of the [`UserPlayingNowPayload::listens`] field. +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] +pub struct UserPlayingNowListen { + pub track_metadata: UserPlayingNowTrackMetadata, + pub playing_now: bool, +} + +/// Type of the [`UserPlayingNowListen::track_metadata`] field. +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] +pub struct UserPlayingNowTrackMetadata { + pub artist_name: String, + pub track_name: String, + pub release_name: Option, + pub additional_info: HashMap, +} + +// --------- GET /1/user/(user_name)/similar-users +// https://listenbrainz.readthedocs.io/en/latest/users/api/core.html#get--1-user-(user_name)-similar-users + +response_type! { + /// Response type for [`Client::user_similar_users`](super::Client::user_similar_users). + #[derive(Debug, Deserialize, Serialize, Clone, PartialEq)] + pub struct UserSimilarUsersResponse { + pub payload: Vec, + } +} + +/// Type of the [`UserSimilarUsersResponse::payload`] field. +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)] +pub struct UserSimilarUsersPayload { + pub user_name: String, + pub similarity: f64, +} + +// --------- GET /1/user/(user_name)/similar-to/(other_user_name) +// https://listenbrainz.readthedocs.io/en/latest/users/api/core.html#get--1-user-(user_name)-similar-to-(other_user_name) + +response_type! { + #[derive(Debug, Deserialize, Serialize)] + pub struct UserSimilarToResponse { + pub user_name: String, + pub similarity: f64, + } +} + +// --------- GET /1/validate-token +// https://listenbrainz.readthedocs.io/en/latest/users/api/core.html#get--1-validate-token + +response_type! { + /// Response type for [`Client::validate_token`](super::Client::validate_token). + #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] + pub struct ValidateTokenResponse { + pub code: u16, + pub message: String, + + pub valid: bool, + pub user_name: Option, + } +} + +// --------- POST /1/delete-listen +// https://listenbrainz.readthedocs.io/en/latest/users/api/core.html#post--1-delete-listen + +response_type! { + /// Response type for [`Client::delete_listen`](super::Client::delete_listen). + #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] + pub struct DeleteListenResponse { + pub status: String, + } +} + +// --------- GET /1/user/(playlist_user_name)/playlists +// https://listenbrainz.readthedocs.io/en/latest/users/api/core.html#get--1-user-(playlist_user_name)-playlists + +response_type! { + /// Response type for [`Client::user_playlists`](super::Client::user_playlists). + #[derive(Debug, Deserialize, Serialize)] + pub struct UserPlaylistsResponse { + pub count: u64, + pub offset: u64, + pub playlist_count: u64, + pub playlists: Vec, + } +} + +// --------- GET /1/user/(playlist_user_name)/playlists/createdfor +// https://listenbrainz.readthedocs.io/en/latest/users/api/core.html#get--1-user-(playlist_user_name)-playlists-createdfor + +response_type! { + /// Response type for [`Client::user_playlists_created_for`](super::Client::user_playlists_created_for). + #[derive(Debug, Deserialize, Serialize)] + pub struct UserPlaylistsCreatedForResponse { + pub count: u64, + pub offset: u64, + pub playlist_count: u64, + pub playlists: Vec, + } +} + +// --------- GET /1/user/(playlist_user_name)/playlists/collaborator +// https://listenbrainz.readthedocs.io/en/latest/users/api/core.html#get--1-user-(playlist_user_name)-playlists-collaborator + +response_type! { + /// Response type for [`Client::user_playlists_collaborator`](super::Client::user_playlists_collaborator). + #[derive(Debug, Deserialize, Serialize)] + pub struct UserPlaylistsCollaboratorResponse { + pub count: u64, + pub offset: u64, + pub playlist_count: u64, + pub playlists: Vec, + } +} + +// --------- GET /1/user/(playlist_user_name)/playlists/recommendations +// https://listenbrainz.readthedocs.io/en/latest/users/api/core.html#get--1-user-(playlist_user_name)-playlists-recommendations + +// TODO + +// --------- GET /1/user/(user_name)/services +// https://listenbrainz.readthedocs.io/en/latest/users/api/core.html#get--1-user-(user_name)-services + +// TODO + +// --------- GET /1/lb-radio/tags +// https://listenbrainz.readthedocs.io/en/latest/users/api/core.html#get--1-lb-radio-tags + +// TODO + +// --------- GET /1/lb-radio/artist/(seed_artist_mbid) +// https://listenbrainz.readthedocs.io/en/latest/users/api/core.html#get--1-lb-radio-artist-(seed_artist_mbid) + +// TODO + +// --------- GET /1/latest-import +// https://listenbrainz.readthedocs.io/en/latest/users/api/core.html#get--1-latest-import + +response_type! { + /// Response type for [`Client::get_latest_import`](super::Client::get_latest_import). + #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] + pub struct GetLatestImportResponse { + pub latest_import: i64, + pub musicbrainz_id: String, + } +} + +// --------- POST /1/latest-import +// https://listenbrainz.readthedocs.io/en/latest/users/api/core.html#post--1-latest-import + +response_type! { + /// Response type for [`Client::update_latest_import`](super::Client::update_latest_import). + #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] + pub struct UpdateLatestImportResponse { + pub status: String, + } +} diff --git a/src/raw/response/mod.rs b/src/raw/response/mod.rs index 98df1d5..8e9f709 100644 --- a/src/raw/response/mod.rs +++ b/src/raw/response/mod.rs @@ -16,6 +16,12 @@ use serde::Serialize; use super::jspf; use crate::Error; +// Sub modules +pub mod core; + +// Reexport of the sub modules +pub use crate::raw::response::core::*; + /// Contains rate limiting information. /// /// ListenBrainz API rate limiting is described in the [API docs]. @@ -93,14 +99,14 @@ macro_rules! response_type { $(#[$meta])* pub struct $name { #[serde(skip)] - pub rate_limit: Option, + pub rate_limit: Option, $(pub $field: $field_ty),* } - impl ResponseType for $name { - fn from_response(response: Response) -> Result { - let response = Error::try_from_error_response(response)?; - let rate_limit = RateLimit::from_headers(&response); + impl crate::raw::response::ResponseType for $name { + fn from_response(response: crate::raw::response::Response) -> Result { + let response = crate::raw::response::Error::try_from_error_response(response)?; + let rate_limit = crate::raw::response::RateLimit::from_headers(&response); let mut result: Self = response.json()?; result.rate_limit = rate_limit; Ok(result) @@ -109,237 +115,8 @@ macro_rules! response_type { } } -// --------- submit-listens - -response_type! { - /// Response type for [`Client::submit_listens`](super::Client::submit_listens). - #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] - pub struct SubmitListensResponse { - pub status: String, - } -} - -// --------- validate-token - -response_type! { - /// Response type for [`Client::validate_token`](super::Client::validate_token). - #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] - pub struct ValidateTokenResponse { - pub code: u16, - pub message: String, - - pub valid: bool, - pub user_name: Option, - } -} - -// --------- delete-listen - -response_type! { - /// Response type for [`Client::delete_listen`](super::Client::delete_listen). - #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] - pub struct DeleteListenResponse { - pub status: String, - } -} - -// --------- user/{user_name}/playlists/collaborator - -response_type! { - /// Response type for [`Client::user_playlists_collaborator`](super::Client::user_playlists_collaborator). - #[derive(Debug, Deserialize, Serialize)] - pub struct UserPlaylistsCollaboratorResponse { - pub count: u64, - pub offset: u64, - pub playlist_count: u64, - pub playlists: Vec, - } -} - -// --------- user/{user_name}/playlists/createdfor - -response_type! { - /// Response type for [`Client::user_playlists_created_for`](super::Client::user_playlists_created_for). - #[derive(Debug, Deserialize, Serialize)] - pub struct UserPlaylistsCreatedForResponse { - pub count: u64, - pub offset: u64, - pub playlist_count: u64, - pub playlists: Vec, - } -} - -// --------- user/{user_name}/similar-users - -response_type! { - /// Response type for [`Client::user_similar_users`](super::Client::user_similar_users). - #[derive(Debug, Deserialize, Serialize)] - pub struct UserSimilarUsersResponse { - pub payload: Vec, - } -} - -/// Type of the [`UserSimilarUsersResponse::payload`] field. -#[derive(Debug, Deserialize, Serialize)] -pub struct UserSimilarUsersPayload { - pub user_name: String, - pub similarity: f64, -} - -// --------- user/{user_name}/listen-count - -response_type! { - /// Response type for [`Client::user_listen_count`](super::Client::user_listen_count). - #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] - pub struct UserListenCountResponse { - pub payload: UserListenCountPayload, - } -} - -/// Type of the [`UserListenCountResponse::payload`] field. -#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] -pub struct UserListenCountPayload { - pub count: u64, -} - -// -------- user/{user_name}/playing-now - -response_type! { - /// Response type for [`Client::user_playing_now`](super::Client::user_playing_now). - #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] - pub struct UserPlayingNowResponse { - pub payload: UserPlayingNowPayload, - } -} - -/// Type of the [`UserPlayingNowResponse::payload`] field. -#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] -pub struct UserPlayingNowPayload { - pub count: u8, - pub user_id: String, - pub listens: Vec, - pub playing_now: bool, -} - -/// Type of the [`UserPlayingNowPayload::listens`] field. -#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] -pub struct UserPlayingNowListen { - pub track_metadata: UserPlayingNowTrackMetadata, - pub playing_now: bool, -} - -/// Type of the [`UserPlayingNowListen::track_metadata`] field. -#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] -pub struct UserPlayingNowTrackMetadata { - pub artist_name: String, - pub track_name: String, - pub release_name: Option, - pub additional_info: HashMap, -} - -// -------- user/{user_name}/similar-to/{other_user_name} - -response_type! { - #[derive(Debug, Deserialize, Serialize)] - pub struct UserSimilarToResponse { - pub user_name: String, - pub similarity: f64, - } -} - -// -------- user/{user_name}/playlists - -response_type! { - /// Response type for [`Client::user_playlists`](super::Client::user_playlists). - #[derive(Debug, Deserialize, Serialize)] - pub struct UserPlaylistsResponse { - pub count: u64, - pub offset: u64, - pub playlist_count: u64, - pub playlists: Vec, - } -} - -// -------- user/{user_name}/listens - -response_type! { - /// Response type for [`Client::user_listens`](super::Client::user_listens). - #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] - pub struct UserListensResponse { - pub payload: UserListensPayload, - } -} - -/// Type of the [`UserListensResponse::payload`] field. -#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] -pub struct UserListensPayload { - pub count: u64, - pub latest_listen_ts: i64, - pub oldest_listen_ts: i64, - pub user_id: String, - pub listens: Vec, -} - -/// Type of the [`UserListensPayload::listens`] field. -#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] -pub struct UserListensListen { - pub user_name: String, - pub inserted_at: i64, - pub listened_at: i64, - pub recording_msid: String, - pub track_metadata: UserListensTrackMetadata, -} - -/// Type of the [`UserListensListen::track_metadata`] field. -#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] -pub struct UserListensTrackMetadata { - pub artist_name: String, - pub track_name: String, - pub release_name: Option, - pub additional_info: HashMap, - pub mbid_mapping: Option, -} - -/// Type of the [`UserListensTrackMetadata::mbid_mapping`] field. -#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] -pub struct UserListensMBIDMapping { - pub artist_mbids: Option>, - pub artists: Option>, - pub recording_mbid: String, - pub recording_name: Option, - pub caa_id: Option, - pub caa_release_mbid: Option, - pub release_mbid: Option, -} - -/// Type of the [`UserListensMBIDMapping::artists`] field. -#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] -pub struct UserListensMappingArtist { - pub artist_mbid: String, - pub artist_credit_name: String, - pub join_phrase: String, -} - -// --------- latest-import (GET) - -response_type! { - /// Response type for [`Client::get_latest_import`](super::Client::get_latest_import). - #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] - pub struct GetLatestImportResponse { - pub latest_import: i64, - pub musicbrainz_id: String, - } -} - -// --------- latest-import (POST) - -response_type! { - /// Response type for [`Client::update_latest_import`](super::Client::update_latest_import). - #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] - pub struct UpdateLatestImportResponse { - pub status: String, - } -} +// Let the childrens access the macro +pub(super) use response_type; // --------- playlist From de1bb7c180ba66633322dc5f0dcf0d7585a326e2 Mon Sep 17 00:00:00 2001 From: RustyNova Date: Tue, 11 Feb 2025 14:03:52 +0000 Subject: [PATCH 03/13] refactor: Moved playlist API responces --- src/raw/response/core/mod.rs | 43 --------- src/raw/response/mod.rs | 44 +-------- src/raw/response/playlists/mod.rs | 146 ++++++++++++++++++++++++++++++ 3 files changed, 148 insertions(+), 85 deletions(-) create mode 100644 src/raw/response/playlists/mod.rs diff --git a/src/raw/response/core/mod.rs b/src/raw/response/core/mod.rs index cd64f69..63871c1 100644 --- a/src/raw/response/core/mod.rs +++ b/src/raw/response/core/mod.rs @@ -3,7 +3,6 @@ use std::collections::HashMap; use serde::Serialize; use super::response_type; -use crate::raw::jspf; use crate::raw::response::Deserialize; // --------- GET /1/search/users/ @@ -191,48 +190,6 @@ response_type! { } } -// --------- GET /1/user/(playlist_user_name)/playlists -// https://listenbrainz.readthedocs.io/en/latest/users/api/core.html#get--1-user-(playlist_user_name)-playlists - -response_type! { - /// Response type for [`Client::user_playlists`](super::Client::user_playlists). - #[derive(Debug, Deserialize, Serialize)] - pub struct UserPlaylistsResponse { - pub count: u64, - pub offset: u64, - pub playlist_count: u64, - pub playlists: Vec, - } -} - -// --------- GET /1/user/(playlist_user_name)/playlists/createdfor -// https://listenbrainz.readthedocs.io/en/latest/users/api/core.html#get--1-user-(playlist_user_name)-playlists-createdfor - -response_type! { - /// Response type for [`Client::user_playlists_created_for`](super::Client::user_playlists_created_for). - #[derive(Debug, Deserialize, Serialize)] - pub struct UserPlaylistsCreatedForResponse { - pub count: u64, - pub offset: u64, - pub playlist_count: u64, - pub playlists: Vec, - } -} - -// --------- GET /1/user/(playlist_user_name)/playlists/collaborator -// https://listenbrainz.readthedocs.io/en/latest/users/api/core.html#get--1-user-(playlist_user_name)-playlists-collaborator - -response_type! { - /// Response type for [`Client::user_playlists_collaborator`](super::Client::user_playlists_collaborator). - #[derive(Debug, Deserialize, Serialize)] - pub struct UserPlaylistsCollaboratorResponse { - pub count: u64, - pub offset: u64, - pub playlist_count: u64, - pub playlists: Vec, - } -} - // --------- GET /1/user/(playlist_user_name)/playlists/recommendations // https://listenbrainz.readthedocs.io/en/latest/users/api/core.html#get--1-user-(playlist_user_name)-playlists-recommendations diff --git a/src/raw/response/mod.rs b/src/raw/response/mod.rs index 8e9f709..1d6b7b5 100644 --- a/src/raw/response/mod.rs +++ b/src/raw/response/mod.rs @@ -18,9 +18,11 @@ use crate::Error; // Sub modules pub mod core; +pub mod playlists; // Reexport of the sub modules pub use crate::raw::response::core::*; +pub use crate::raw::response::playlists::*; /// Contains rate limiting information. /// @@ -118,48 +120,6 @@ macro_rules! response_type { // Let the childrens access the macro pub(super) use response_type; -// --------- playlist - -response_type! { - /// Response type for [`Client::playlist`](super::Client::get_playlist). - #[derive(Debug, Deserialize, Serialize)] - pub struct GetPlaylistResponse { - pub playlist: jspf::PlaylistInfo, - } -} - -// --------- playlist/create - -response_type! { - /// Response type for [`Client::playlist_create`](super::Client::playlist_create). - #[derive(Debug, Deserialize, Serialize)] - pub struct PlaylistCreateResponse { - pub playlist_mbid: String, - pub status: String, - } -} - -// --------- playlist/{playlist_mbid}/delete - -response_type! { - /// Response type for [`Client::playlist_delete`](super::Client::playlist_delete). - #[derive(Debug, Deserialize, Serialize)] - pub struct PlaylistDeleteResponse { - pub status: String, - } -} - -// --------- playlist/{playlist_mbid}/copy - -response_type! { - /// Response type for [`Client::playlist_copy`](super::Client::playlist_copy). - #[derive(Debug, Deserialize, Serialize)] - pub struct PlaylistCopyResponse { - pub playlist_mbid: String, - pub status: String, - } -} - // --------- stats/sitewide/artists response_type! { diff --git a/src/raw/response/playlists/mod.rs b/src/raw/response/playlists/mod.rs new file mode 100644 index 0000000..8ff4379 --- /dev/null +++ b/src/raw/response/playlists/mod.rs @@ -0,0 +1,146 @@ +use serde::Deserialize; +use serde::Serialize; + +use crate::raw::jspf; +use crate::raw::response::response_type; + +// --------- GET /1/user/(playlist_user_name)/playlists +// https://listenbrainz.readthedocs.io/en/latest/users/api/playlist.html#get--1-user-(playlist_user_name)-playlists + +response_type! { + /// Response type for [`Client::user_playlists`](super::Client::user_playlists). + #[derive(Debug, Deserialize, Serialize)] + pub struct UserPlaylistsResponse { + pub count: u64, + pub offset: u64, + pub playlist_count: u64, + pub playlists: Vec, + } +} + +// --------- GET /1/user/(playlist_user_name)/playlists/createdfor +// https://listenbrainz.readthedocs.io/en/latest/users/api/playlist.html#get--1-user-(playlist_user_name)-playlists-createdfor + +response_type! { + /// Response type for [`Client::user_playlists_created_for`](super::Client::user_playlists_created_for). + #[derive(Debug, Deserialize, Serialize)] + pub struct UserPlaylistsCreatedForResponse { + pub count: u64, + pub offset: u64, + pub playlist_count: u64, + pub playlists: Vec, + } +} + +// --------- GET /1/user/(playlist_user_name)/playlists/collaborator +// https://listenbrainz.readthedocs.io/en/latest/users/api/playlist.html#get--1-user-(playlist_user_name)-playlists-collaborator + +response_type! { + /// Response type for [`Client::user_playlists_collaborator`](super::Client::user_playlists_collaborator). + #[derive(Debug, Deserialize, Serialize)] + pub struct UserPlaylistsCollaboratorResponse { + pub count: u64, + pub offset: u64, + pub playlist_count: u64, + pub playlists: Vec, + } +} + +// --------- POST /1/playlist/create +// https://listenbrainz.readthedocs.io/en/latest/users/api/playlist.html#post--1-playlist-create + +response_type! { + /// Response type for [`Client::playlist_create`](super::Client::playlist_create). + #[derive(Debug, Deserialize, Serialize)] + pub struct PlaylistCreateResponse { + pub playlist_mbid: String, + pub status: String, + } +} + +// --------- GET /1/playlist/search +// https://listenbrainz.readthedocs.io/en/latest/users/api/playlist.html#get--1-playlist-search + +// TODO + +// --------- GET /1/playlist/(playlist_mbid) +// https://listenbrainz.readthedocs.io/en/latest/users/api/playlist.html#get--1-playlist-(playlist_mbid) + +response_type! { + /// Response type for [`Client::playlist`](super::Client::get_playlist). + #[derive(Debug, Deserialize, Serialize)] + pub struct GetPlaylistResponse { + pub playlist: jspf::PlaylistInfo, + } +} + +// --------- GET /1/playlist/(playlist_mbid)/xspf +// https://listenbrainz.readthedocs.io/en/latest/users/api/playlist.html#get--1-playlist-(playlist_mbid)-xspf + +// TODO + +// --------- POST /1/playlist/(playlist_mbid)/item/add +// https://listenbrainz.readthedocs.io/en/latest/users/api/playlist.html#post--1-playlist-(playlist_mbid)-item-add +// Or +// --------- POST /1/playlist/(playlist_mbid)/item/add/(int: offset) +// https://listenbrainz.readthedocs.io/en/latest/users/api/playlist.html#post--1-playlist-(playlist_mbid)-item-add-(int-offset) + +// TODO + +// --------- POST /1/playlist/(playlist_mbid)/item/move +// https://listenbrainz.readthedocs.io/en/latest/users/api/playlist.html#post--1-playlist-(playlist_mbid)-item-move + +// TODO + +// --------- POST /1/playlist/(playlist_mbid)/item/delete +// https://listenbrainz.readthedocs.io/en/latest/users/api/playlist.html#post--1-playlist-(playlist_mbid)-item-delete + +// TODO + +// --------- POST /1/playlist/(playlist_mbid)/delete +// https://listenbrainz.readthedocs.io/en/latest/users/api/playlist.html#post--1-playlist-(playlist_mbid)-delete + +response_type! { + /// Response type for [`Client::playlist_delete`](super::Client::playlist_delete). + #[derive(Debug, Deserialize, Serialize)] + pub struct PlaylistDeleteResponse { + pub status: String, + } +} + +// --------- POST /1/playlist/(playlist_mbid)/copy +// https://listenbrainz.readthedocs.io/en/latest/users/api/playlist.html#post--1-playlist-(playlist_mbid)-copy + +response_type! { + /// Response type for [`Client::playlist_copy`](super::Client::playlist_copy). + #[derive(Debug, Deserialize, Serialize)] + pub struct PlaylistCopyResponse { + pub playlist_mbid: String, + pub status: String, + } +} + +// --------- POST /1/playlist/(playlist_mbid)/export/(service) +// https://listenbrainz.readthedocs.io/en/latest/users/api/playlist.html#post--1-playlist-(playlist_mbid)-export-(service) + +// TODO + +// --------- GET /1/playlist/import/(service) +// https://listenbrainz.readthedocs.io/en/latest/users/api/playlist.html#get--1-playlist-import-(service) + +// TODO + +// --------- GET /1/playlist/spotify/(playlist_id)/tracks +// https://listenbrainz.readthedocs.io/en/latest/users/api/playlist.html#get--1-playlist-spotify-(playlist_id)-tracks + +// TODO + +// --------- GET /1/playlist/apple_music/(playlist_id)/tracks +// https://listenbrainz.readthedocs.io/en/latest/users/api/playlist.html#get--1-playlist-apple_music-(playlist_id)-tracks + +// TODO + +// --------- POST /1/playlist/export-jspf/(service) +// https://listenbrainz.readthedocs.io/en/latest/users/api/playlist.html#post--1-playlist-export-jspf-(service) + +// TODO From 898bd86c67a41e839bed20d96050de99b563c70d Mon Sep 17 00:00:00 2001 From: RustyNova Date: Tue, 11 Feb 2025 14:15:57 +0000 Subject: [PATCH 04/13] feat: added recordings mod --- src/raw/response/mod.rs | 3 +++ src/raw/response/recordings/mod.rs | 3 +++ 2 files changed, 6 insertions(+) create mode 100644 src/raw/response/recordings/mod.rs diff --git a/src/raw/response/mod.rs b/src/raw/response/mod.rs index 1d6b7b5..6e26850 100644 --- a/src/raw/response/mod.rs +++ b/src/raw/response/mod.rs @@ -1,3 +1,4 @@ + //! Low-level response data models. //! //! Every response type has the `rate_limit` field, which contains rate limiting @@ -19,10 +20,12 @@ use crate::Error; // Sub modules pub mod core; pub mod playlists; +pub mod recordings; // Reexport of the sub modules pub use crate::raw::response::core::*; pub use crate::raw::response::playlists::*; +pub use crate::raw::response::recordings::*; /// Contains rate limiting information. /// diff --git a/src/raw/response/recordings/mod.rs b/src/raw/response/recordings/mod.rs new file mode 100644 index 0000000..77f1d51 --- /dev/null +++ b/src/raw/response/recordings/mod.rs @@ -0,0 +1,3 @@ +//TODO: https://listenbrainz.readthedocs.io/en/latest/users/api/recordings.html +// Currently no api responses have been made for this page. +// The header comments will be made as needed \ No newline at end of file From a8800719994f9eadad5a128499e0f88fc21717a7 Mon Sep 17 00:00:00 2001 From: RustyNova Date: Tue, 11 Feb 2025 14:30:35 +0000 Subject: [PATCH 05/13] refactor: moved stats API responces --- src/raw/response/mod.rs | 263 +-------------------------- src/raw/response/statistics/mod.rs | 274 +++++++++++++++++++++++++++++ 2 files changed, 276 insertions(+), 261 deletions(-) create mode 100644 src/raw/response/statistics/mod.rs diff --git a/src/raw/response/mod.rs b/src/raw/response/mod.rs index 6e26850..524093f 100644 --- a/src/raw/response/mod.rs +++ b/src/raw/response/mod.rs @@ -1,4 +1,3 @@ - //! Low-level response data models. //! //! Every response type has the `rate_limit` field, which contains rate limiting @@ -7,8 +6,6 @@ #![allow(missing_docs)] -use std::collections::HashMap; - use attohttpc::Response; use serde::de::DeserializeOwned; use serde::Deserialize; @@ -21,11 +18,13 @@ use crate::Error; pub mod core; pub mod playlists; pub mod recordings; +pub mod statistics; // Reexport of the sub modules pub use crate::raw::response::core::*; pub use crate::raw::response::playlists::*; pub use crate::raw::response::recordings::*; +pub use crate::raw::response::statistics::*; /// Contains rate limiting information. /// @@ -123,232 +122,6 @@ macro_rules! response_type { // Let the childrens access the macro pub(super) use response_type; -// --------- stats/sitewide/artists - -response_type! { - /// Response type for [`Client::stats_sitewide_artists`](super::Client::stats_sitewide_artists). - #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] - pub struct StatsSitewideArtistsResponse { - pub payload: StatsSitewideArtistsPayload, - } -} - -/// Type of the [`StatsSitewideArtistsResponse::payload`] field. -#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] -pub struct StatsSitewideArtistsPayload { - pub artists: Vec, - 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::artists`] field. -#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] -pub struct StatsSitewideArtistsArtist { - pub artist_mbids: Option>, - pub artist_name: String, - pub listen_count: u64, -} - -// --------- stats/user/{user_name}/listening-activity - -response_type! { - /// Response type for [`Client::stats_user_listening_activity`](super::Client::stats_user_listening_activity). - #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] - pub struct StatsUserListeningActivityResponse { - pub payload: StatsUserListeningActivityPayload, - } -} - -/// Type of the [`StatsUserListeningActivityResponse::payload`] field. -#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] -pub struct StatsUserListeningActivityPayload { - pub user_id: String, - pub listening_activity: Vec, - pub from_ts: i64, - pub to_ts: i64, - pub last_updated: i64, -} - -/// Type of the [`StatsUserListeningActivityPayload::listening_activity`] field. -#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] -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 - -response_type! { - /// Response type for [`Client::stats_user_daily_activity`](super::Client::stats_user_daily_activity). - #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] - pub struct StatsUserDailyActivityResponse { - pub payload: StatsUserDailyActivityPayload, - } -} - -/// Type of the [`StatsUserDailyActivityResponse::payload`] field. -#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] -pub struct StatsUserDailyActivityPayload { - pub user_id: String, - pub daily_activity: StatsUserDailyActivityDailyActivity, - pub from_ts: i64, - pub to_ts: i64, - pub last_updated: i64, - pub stats_range: String, -} - -/// Type of the [`StatsUserDailyActivityPayload::daily_activity`] field. -#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] -pub struct StatsUserDailyActivityDailyActivity { - pub days: HashMap>, -} - -/// Type of the [`StatsUserDailyActivityDailyActivity::days`] field. -#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] -pub struct StatsUserDailyActivityHour { - pub hour: u8, - pub listen_count: u64, -} - -// --------- stats/user/{user_name}/recordings - -response_type! { - /// Response type of [`Client::stats_user_recordings`](super::Client::stats_user_recordings). - #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] - pub struct StatsUserRecordingsResponse { - pub payload: StatsUserRecordingsPayload, - } -} - -/// Type of the [`StatsUserRecordingsResponse::payload`] field. -#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] -pub struct StatsUserRecordingsPayload { - pub recordings: Vec, - 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, Serialize, Clone, PartialEq, Eq)] -pub struct StatsUserRecordingsRecording { - pub artist_mbids: Option>, - pub artist_msid: Option, - pub artist_name: String, - pub listen_count: u64, - pub recording_mbid: Option, - pub recording_msid: Option, - pub release_mbid: Option, - pub release_msid: Option, - pub release_name: Option, - pub track_name: Option, -} - -// --------- stats/user/{user_name}/artist-map - -response_type! { - /// Response type of [`Client::stats_user_artist_map`](super::Client::stats_user_artist_map). - #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] - pub struct StatsUserArtistMapResponse { - pub payload: StatsUserArtistMapPayload, - } -} - -/// Type of the [`StatsUserArtistMapResponse::payload`] field. -#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] -pub struct StatsUserArtistMapPayload { - pub artist_map: Vec, - 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, Serialize, Clone, PartialEq, Eq)] -pub struct StatsUserArtistMapCountry { - pub country: String, - pub artist_count: u64, -} - -// --------- stats/user/{user_name}/releases - -response_type! { - /// Response type for [`Client::stats_user_releases`](super::Client::stats_user_releases). - #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] - pub struct StatsUserReleasesResponse { - pub payload: StatsUserReleasesPayload, - } -} - -/// Type of the [`StatsUserReleasesResponse::payload`] field. -#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] -pub struct StatsUserReleasesPayload { - pub releases: Vec, - 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, Serialize, Clone, PartialEq, Eq)] -pub struct StatsUserReleasesRelease { - pub artist_mbids: Option>, - pub artist_msid: Option, - pub artist_name: String, - pub listen_count: u64, - pub release_mbid: Option, - pub release_msid: Option, - pub release_name: String, -} - -// --------- stats/user/{user_name}/artists - -response_type! { - /// Response type of [`Client::stats_user_artists`](super::Client::stats_user_artists). - #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] - pub struct StatsUserArtistsResponse { - pub payload: StatsUserArtistsPayload, - } -} - -/// Type of the [`StatsUserArtistsResponse::payload`] field. -#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] -pub struct StatsUserArtistsPayload { - pub artists: Vec, - 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, Serialize, Clone, PartialEq, Eq)] -pub struct StatsUserArtistsArtist { - pub artist_mbids: Option>, - pub artist_msid: Option, - pub artist_name: String, - pub listen_count: u64, -} - // --------- status/get-dump-info response_type! { @@ -363,39 +136,7 @@ response_type! { } } -// ---------- stats/release-group/(release_group_mbid)/listeners - -response_type! { - /// Response type for [`Client::stats_release_group_listeners`](super::Client::stats_release_group_listeners). - #[derive(Debug, Deserialize, Serialize)] - pub struct StatsReleaseGroupListenersResponse { - pub payload: StatsReleaseGroupListenersPayload - } -} - -/// Type of the [`StatsReleaseGroupListenersResponse::payload`] field. -#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] -pub struct StatsReleaseGroupListenersPayload { - pub artist_mbids: Vec, - pub artist_name: String, - pub caa_id: Option, - pub caa_release_mbid: Option, - pub from_ts: i64, - pub last_updated: i64, - pub listeners: Vec, - pub release_group_mbid: String, - pub release_group_name: String, - pub stats_range: String, - pub to_ts: i64, - pub total_listen_count: i64, -} -/// Type of the [`StatsReleaseGroupListenersPayload::listeners`] field. -#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] -pub struct StatsReleaseGroupListenersListeners { - pub listen_count: u64, - pub username_name: String, -} // --------- user/{user_name}/followers diff --git a/src/raw/response/statistics/mod.rs b/src/raw/response/statistics/mod.rs new file mode 100644 index 0000000..d05a5eb --- /dev/null +++ b/src/raw/response/statistics/mod.rs @@ -0,0 +1,274 @@ +use std::collections::HashMap; + +use serde::Deserialize; +use serde::Serialize; + +use crate::raw::response::response_type; + +// --------- GET /1/stats/user/(user_name)/artists +// https://listenbrainz.readthedocs.io/en/latest/users/api/statistics.html#get--1-stats-user-(user_name)-artists + +response_type! { + /// Response type of [`Client::stats_user_artists`](super::Client::stats_user_artists). + #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] + pub struct StatsUserArtistsResponse { + pub payload: StatsUserArtistsPayload, + } +} + +/// Type of the [`StatsUserArtistsResponse::payload`] field. +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] +pub struct StatsUserArtistsPayload { + pub artists: Vec, + 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, Serialize, Clone, PartialEq, Eq)] +pub struct StatsUserArtistsArtist { + pub artist_mbids: Option>, + pub artist_msid: Option, + pub artist_name: String, + pub listen_count: u64, +} + +// --------- GET /1/stats/user/(user_name)/releases +// https://listenbrainz.readthedocs.io/en/latest/users/api/statistics.html#get--1-stats-user-(user_name)-releases + +response_type! { + /// Response type for [`Client::stats_user_releases`](super::Client::stats_user_releases). + #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] + pub struct StatsUserReleasesResponse { + pub payload: StatsUserReleasesPayload, + } +} + + +/// Type of the [`StatsUserReleasesResponse::payload`] field. +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] +pub struct StatsUserReleasesPayload { + pub releases: Vec, + 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, Serialize, Clone, PartialEq, Eq)] +pub struct StatsUserReleasesRelease { + pub artist_mbids: Option>, + pub artist_msid: Option, + pub artist_name: String, + pub listen_count: u64, + pub release_mbid: Option, + pub release_msid: Option, + pub release_name: String, +} + +// --------- GET /1/stats/user/(user_name)/recordings +// https://listenbrainz.readthedocs.io/en/latest/users/api/statistics.html#get--1-stats-user-(user_name)-recordings + +response_type! { + /// Response type of [`Client::stats_user_recordings`](super::Client::stats_user_recordings). + #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] + pub struct StatsUserRecordingsResponse { + pub payload: StatsUserRecordingsPayload, + } +} + +/// Type of the [`StatsUserRecordingsResponse::payload`] field. +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] +pub struct StatsUserRecordingsPayload { + pub recordings: Vec, + 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, Serialize, Clone, PartialEq, Eq)] +pub struct StatsUserRecordingsRecording { + pub artist_mbids: Option>, + pub artist_msid: Option, + pub artist_name: String, + pub listen_count: u64, + pub recording_mbid: Option, + pub recording_msid: Option, + pub release_mbid: Option, + pub release_msid: Option, + pub release_name: Option, + pub track_name: Option, +} + +// --------- GET /1/stats/user/(user_name)/listening-activity +// https://listenbrainz.readthedocs.io/en/latest/users/api/statistics.html#get--1-stats-user-(user_name)-listening-activity + +response_type! { + /// Response type for [`Client::stats_user_listening_activity`](super::Client::stats_user_listening_activity). + #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] + pub struct StatsUserListeningActivityResponse { + pub payload: StatsUserListeningActivityPayload, + } +} + +/// Type of the [`StatsUserListeningActivityResponse::payload`] field. +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] +pub struct StatsUserListeningActivityPayload { + pub user_id: String, + pub listening_activity: Vec, + pub from_ts: i64, + pub to_ts: i64, + pub last_updated: i64, +} + +/// Type of the [`StatsUserListeningActivityPayload::listening_activity`] field. +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] +pub struct StatsUserListeningActivityListeningActivity { + pub listen_count: u64, + pub from_ts: i64, + pub to_ts: i64, + pub time_range: String, +} + +// --------- GET /1/stats/user/(user_name)/daily-activity +// https://listenbrainz.readthedocs.io/en/latest/users/api/statistics.html#get--1-stats-user-(user_name)-daily-activity + +response_type! { + /// Response type for [`Client::stats_user_daily_activity`](super::Client::stats_user_daily_activity). + #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] + pub struct StatsUserDailyActivityResponse { + pub payload: StatsUserDailyActivityPayload, + } +} + +/// Type of the [`StatsUserDailyActivityResponse::payload`] field. +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] +pub struct StatsUserDailyActivityPayload { + pub user_id: String, + pub daily_activity: StatsUserDailyActivityDailyActivity, + pub from_ts: i64, + pub to_ts: i64, + pub last_updated: i64, + pub stats_range: String, +} + +/// Type of the [`StatsUserDailyActivityPayload::daily_activity`] field. +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] +pub struct StatsUserDailyActivityDailyActivity { + pub days: HashMap>, +} + +/// Type of the [`StatsUserDailyActivityDailyActivity::days`] field. +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] +pub struct StatsUserDailyActivityHour { + pub hour: u8, + pub listen_count: u64, +} + +// --------- GET /1/stats/user/(user_name)/artist-map +// https://listenbrainz.readthedocs.io/en/latest/users/api/statistics.html#get--1-stats-user-(user_name)-artist-map + +response_type! { + /// Response type of [`Client::stats_user_artist_map`](super::Client::stats_user_artist_map). + #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] + pub struct StatsUserArtistMapResponse { + pub payload: StatsUserArtistMapPayload, + } +} + +/// Type of the [`StatsUserArtistMapResponse::payload`] field. +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] +pub struct StatsUserArtistMapPayload { + pub artist_map: Vec, + 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, Serialize, Clone, PartialEq, Eq)] +pub struct StatsUserArtistMapCountry { + pub country: String, + pub artist_count: u64, +} + +// --------- GET /1/stats/release-group/(release_group_mbid)/listeners +// https://listenbrainz.readthedocs.io/en/latest/users/api/statistics.html#get--1-stats-release-group-(release_group_mbid)-listeners + +response_type! { + /// Response type for [`Client::stats_release_group_listeners`](super::Client::stats_release_group_listeners). + #[derive(Debug, Deserialize, Serialize)] + pub struct StatsReleaseGroupListenersResponse { + pub payload: StatsReleaseGroupListenersPayload + } +} + +/// Type of the [`StatsReleaseGroupListenersResponse::payload`] field. +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] +pub struct StatsReleaseGroupListenersPayload { + pub artist_mbids: Vec, + pub artist_name: String, + pub caa_id: Option, + pub caa_release_mbid: Option, + pub from_ts: i64, + pub last_updated: i64, + pub listeners: Vec, + pub release_group_mbid: String, + pub release_group_name: String, + pub stats_range: String, + pub to_ts: i64, + pub total_listen_count: i64, +} + +/// Type of the [`StatsReleaseGroupListenersPayload::listeners`] field. +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] +pub struct StatsReleaseGroupListenersListeners { + pub listen_count: u64, + pub username_name: String, +} + +// --------- GET /1/stats/sitewide/artists +// https://listenbrainz.readthedocs.io/en/latest/users/api/statistics.html#get--1-stats-sitewide-artists +response_type! { + /// Response type for [`Client::stats_sitewide_artists`](super::Client::stats_sitewide_artists). + #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] + pub struct StatsSitewideArtistsResponse { + pub payload: StatsSitewideArtistsPayload, + } +} + +/// Type of the [`StatsSitewideArtistsResponse::payload`] field. +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] +pub struct StatsSitewideArtistsPayload { + pub artists: Vec, + 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::artists`] field. +#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] +pub struct StatsSitewideArtistsArtist { + pub artist_mbids: Option>, + pub artist_name: String, + pub listen_count: u64, +} \ No newline at end of file From db364831b7bac791f22a8c39934ecd69221cd031 Mon Sep 17 00:00:00 2001 From: RustyNova Date: Tue, 11 Feb 2025 14:32:34 +0000 Subject: [PATCH 06/13] feat: added popularity mod --- src/raw/response/mod.rs | 2 ++ src/raw/response/popularity/mod.rs | 3 +++ 2 files changed, 5 insertions(+) create mode 100644 src/raw/response/popularity/mod.rs diff --git a/src/raw/response/mod.rs b/src/raw/response/mod.rs index 524093f..f6750f8 100644 --- a/src/raw/response/mod.rs +++ b/src/raw/response/mod.rs @@ -1,3 +1,4 @@ + //! Low-level response data models. //! //! Every response type has the `rate_limit` field, which contains rate limiting @@ -19,6 +20,7 @@ pub mod core; pub mod playlists; pub mod recordings; pub mod statistics; +pub mod popularity; // Reexport of the sub modules pub use crate::raw::response::core::*; diff --git a/src/raw/response/popularity/mod.rs b/src/raw/response/popularity/mod.rs new file mode 100644 index 0000000..fe6217f --- /dev/null +++ b/src/raw/response/popularity/mod.rs @@ -0,0 +1,3 @@ +//TODO: https://listenbrainz.readthedocs.io/en/latest/users/api/popularity.html +// Currently no api responses have been made for this page. +// The header comments will be made as needed \ No newline at end of file From a29cd9be4506a31af677a05887a7098ea8f272ac Mon Sep 17 00:00:00 2001 From: RustyNova Date: Tue, 11 Feb 2025 14:36:38 +0000 Subject: [PATCH 07/13] feat: added metadata mod --- src/raw/response/metadata/mod.rs | 3 +++ src/raw/response/mod.rs | 4 ++++ 2 files changed, 7 insertions(+) create mode 100644 src/raw/response/metadata/mod.rs diff --git a/src/raw/response/metadata/mod.rs b/src/raw/response/metadata/mod.rs new file mode 100644 index 0000000..fb6977d --- /dev/null +++ b/src/raw/response/metadata/mod.rs @@ -0,0 +1,3 @@ +//TODO: https://listenbrainz.readthedocs.io/en/latest/users/api/metadata.html +// Currently no api responses have been made for this page. +// The header comments will be made as needed \ No newline at end of file diff --git a/src/raw/response/mod.rs b/src/raw/response/mod.rs index f6750f8..e6910f9 100644 --- a/src/raw/response/mod.rs +++ b/src/raw/response/mod.rs @@ -1,4 +1,5 @@ + //! Low-level response data models. //! //! Every response type has the `rate_limit` field, which contains rate limiting @@ -21,12 +22,15 @@ pub mod playlists; pub mod recordings; pub mod statistics; pub mod popularity; +pub mod metadata; // Reexport of the sub modules pub use crate::raw::response::core::*; pub use crate::raw::response::playlists::*; pub use crate::raw::response::recordings::*; pub use crate::raw::response::statistics::*; +pub use crate::raw::response::popularity::*; +pub use crate::raw::response::metadata::*; /// Contains rate limiting information. /// From b58ce6dd85f2ca59dd234d944ca0c20334d53d4c Mon Sep 17 00:00:00 2001 From: RustyNova Date: Tue, 11 Feb 2025 14:43:03 +0000 Subject: [PATCH 08/13] refactor: move social API responces --- src/raw/response/mod.rs | 56 ++++------------------------------ src/raw/response/social/mod.rs | 53 ++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 50 deletions(-) create mode 100644 src/raw/response/social/mod.rs diff --git a/src/raw/response/mod.rs b/src/raw/response/mod.rs index e6910f9..d83c73a 100644 --- a/src/raw/response/mod.rs +++ b/src/raw/response/mod.rs @@ -1,5 +1,3 @@ - - //! Low-level response data models. //! //! Every response type has the `rate_limit` field, which contains rate limiting @@ -18,19 +16,21 @@ use crate::Error; // Sub modules pub mod core; +pub mod metadata; pub mod playlists; +pub mod popularity; pub mod recordings; +pub mod social; pub mod statistics; -pub mod popularity; -pub mod metadata; // Reexport of the sub modules pub use crate::raw::response::core::*; +pub use crate::raw::response::metadata::*; pub use crate::raw::response::playlists::*; +pub use crate::raw::response::popularity::*; pub use crate::raw::response::recordings::*; +pub use crate::raw::response::social::*; pub use crate::raw::response::statistics::*; -pub use crate::raw::response::popularity::*; -pub use crate::raw::response::metadata::*; /// Contains rate limiting information. /// @@ -141,47 +141,3 @@ response_type! { pub timestamp: String, } } - - - -// --------- user/{user_name}/followers - -response_type! { - /// Response type for [`Client::user_followers`](super::Client::user_followers). - #[derive(Debug, Deserialize, Serialize)] - pub struct UserFollowersResponse { - pub followers: Vec, - pub user: String, - } -} - -// --------- user/{user_name}/following - -response_type! { - /// Response type for [`Client::user_following`](super::Client::user_following). - #[derive(Debug, Deserialize, Serialize)] - pub struct UserFollowingResponse { - pub following: Vec, - pub user: String, - } -} - -// --------- user/{user_name}/unfollow - -response_type! { - /// Response type for [`Client::user_unfollow`](super::Client::user_unfollow). - #[derive(Debug, Deserialize, Serialize)] - pub struct UserUnfollowResponse { - pub status: String, - } -} - -// --------- user/{user_name}/follow - -response_type! { - /// Response type for [`Client::user_follow`](super::Client::user_follow). - #[derive(Debug, Deserialize, Serialize)] - pub struct UserFollowResponse { - pub status: String, - } -} diff --git a/src/raw/response/social/mod.rs b/src/raw/response/social/mod.rs new file mode 100644 index 0000000..dc99d67 --- /dev/null +++ b/src/raw/response/social/mod.rs @@ -0,0 +1,53 @@ +// --------- user/{user_name}/followers + +use serde::Deserialize; +use serde::Serialize; + +use crate::raw::response::response_type; + +// --------- GET /1/user/(user_name)/followers +// https://listenbrainz.readthedocs.io/en/latest/users/api/social.html#get--1-user-(user_name)-followers + +response_type! { + /// Response type for [`Client::user_followers`](super::Client::user_followers). + #[derive(Debug, Deserialize, Serialize)] + pub struct UserFollowersResponse { + pub followers: Vec, + pub user: String, + } +} + +// --------- GET /1/user/(user_name)/following +// https://listenbrainz.readthedocs.io/en/latest/users/api/social.html#get--1-user-(user_name)-following + +response_type! { + /// Response type for [`Client::user_following`](super::Client::user_following). + #[derive(Debug, Deserialize, Serialize)] + pub struct UserFollowingResponse { + pub following: Vec, + pub user: String, + } +} + +// --------- POST /1/user/(user_name)/follow +// https://listenbrainz.readthedocs.io/en/latest/users/api/social.html#post--1-user-(user_name)-follow + +response_type! { + /// Response type for [`Client::user_follow`](super::Client::user_follow). + #[derive(Debug, Deserialize, Serialize)] + pub struct UserFollowResponse { + pub status: String, + } +} + +// --------- POST /1/user/(user_name)/unfollow +// https://listenbrainz.readthedocs.io/en/latest/users/api/social.html#post--1-user-(user_name)-unfollow + +response_type! { + /// Response type for [`Client::user_unfollow`](super::Client::user_unfollow). + #[derive(Debug, Deserialize, Serialize)] + pub struct UserUnfollowResponse { + pub status: String, + } +} + From 02d511305f2992f537a96d3b238f86566e07109d Mon Sep 17 00:00:00 2001 From: RustyNova Date: Tue, 11 Feb 2025 15:07:44 +0000 Subject: [PATCH 09/13] feat: added recommendations mod --- src/raw/response/mod.rs | 3 ++- src/raw/response/recommendations/mod.rs | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 src/raw/response/recommendations/mod.rs diff --git a/src/raw/response/mod.rs b/src/raw/response/mod.rs index d83c73a..0e51e21 100644 --- a/src/raw/response/mod.rs +++ b/src/raw/response/mod.rs @@ -11,7 +11,6 @@ use serde::de::DeserializeOwned; use serde::Deserialize; use serde::Serialize; -use super::jspf; use crate::Error; // Sub modules @@ -19,6 +18,7 @@ pub mod core; pub mod metadata; pub mod playlists; pub mod popularity; +pub mod recommendations; pub mod recordings; pub mod social; pub mod statistics; @@ -28,6 +28,7 @@ pub use crate::raw::response::core::*; pub use crate::raw::response::metadata::*; pub use crate::raw::response::playlists::*; pub use crate::raw::response::popularity::*; +pub use crate::raw::response::recommendations::*; pub use crate::raw::response::recordings::*; pub use crate::raw::response::social::*; pub use crate::raw::response::statistics::*; diff --git a/src/raw/response/recommendations/mod.rs b/src/raw/response/recommendations/mod.rs new file mode 100644 index 0000000..30c6bd2 --- /dev/null +++ b/src/raw/response/recommendations/mod.rs @@ -0,0 +1,3 @@ +//TODO: https://listenbrainz.readthedocs.io/en/latest/users/api/recommendation.html +// Currently no api responses have been made for this page. +// The header comments will be made as needed \ No newline at end of file From 384ae94c046851c135770318e3904ab583974a66 Mon Sep 17 00:00:00 2001 From: RustyNova Date: Tue, 11 Feb 2025 15:09:08 +0000 Subject: [PATCH 10/13] feat: added art mod --- src/raw/response/art/mod.rs | 3 +++ src/raw/response/mod.rs | 2 ++ 2 files changed, 5 insertions(+) create mode 100644 src/raw/response/art/mod.rs diff --git a/src/raw/response/art/mod.rs b/src/raw/response/art/mod.rs new file mode 100644 index 0000000..4be253b --- /dev/null +++ b/src/raw/response/art/mod.rs @@ -0,0 +1,3 @@ +//TODO: https://listenbrainz.readthedocs.io/en/latest/users/api/art.html +// Currently no api responses have been made for this page. +// The header comments will be made as needed \ No newline at end of file diff --git a/src/raw/response/mod.rs b/src/raw/response/mod.rs index 0e51e21..b12939b 100644 --- a/src/raw/response/mod.rs +++ b/src/raw/response/mod.rs @@ -14,6 +14,7 @@ use serde::Serialize; use crate::Error; // Sub modules +pub mod art; pub mod core; pub mod metadata; pub mod playlists; @@ -24,6 +25,7 @@ pub mod social; pub mod statistics; // Reexport of the sub modules +pub use crate::raw::response::art::*; pub use crate::raw::response::core::*; pub use crate::raw::response::metadata::*; pub use crate::raw::response::playlists::*; From 48d1c50c1019446808b28e09abf9f64a6dacaa50 Mon Sep 17 00:00:00 2001 From: RustyNova Date: Tue, 11 Feb 2025 15:10:03 +0000 Subject: [PATCH 11/13] feat: added setting mod --- src/raw/response/mod.rs | 2 ++ src/raw/response/settings/mod.rs | 3 +++ 2 files changed, 5 insertions(+) create mode 100644 src/raw/response/settings/mod.rs diff --git a/src/raw/response/mod.rs b/src/raw/response/mod.rs index b12939b..424b816 100644 --- a/src/raw/response/mod.rs +++ b/src/raw/response/mod.rs @@ -21,6 +21,7 @@ pub mod playlists; pub mod popularity; pub mod recommendations; pub mod recordings; +pub mod settings; pub mod social; pub mod statistics; @@ -32,6 +33,7 @@ pub use crate::raw::response::playlists::*; pub use crate::raw::response::popularity::*; pub use crate::raw::response::recommendations::*; pub use crate::raw::response::recordings::*; +pub use crate::raw::response::settings::*; pub use crate::raw::response::social::*; pub use crate::raw::response::statistics::*; diff --git a/src/raw/response/settings/mod.rs b/src/raw/response/settings/mod.rs new file mode 100644 index 0000000..95d0c03 --- /dev/null +++ b/src/raw/response/settings/mod.rs @@ -0,0 +1,3 @@ +//TODO: https://listenbrainz.readthedocs.io/en/latest/users/api/settings.html +// Currently no api responses have been made for this page. +// The header comments will be made as needed \ No newline at end of file From 161aee93e68073cfa735c10a85a8cf9c7a829d4e Mon Sep 17 00:00:00 2001 From: RustyNova Date: Tue, 11 Feb 2025 15:14:17 +0000 Subject: [PATCH 12/13] refactor: move misc API responces --- src/raw/response/misc/mod.rs | 19 +++++++++++++++++++ src/raw/response/mod.rs | 17 ++--------------- 2 files changed, 21 insertions(+), 15 deletions(-) create mode 100644 src/raw/response/misc/mod.rs diff --git a/src/raw/response/misc/mod.rs b/src/raw/response/misc/mod.rs new file mode 100644 index 0000000..5b84ab4 --- /dev/null +++ b/src/raw/response/misc/mod.rs @@ -0,0 +1,19 @@ +use serde::Deserialize; +use serde::Serialize; + +use crate::raw::response::response_type; + +// --------- GET /1/status/get-dump-info +// https://listenbrainz.readthedocs.io/en/latest/users/api/misc.html#get--1-status-get-dump-info + +response_type! { + /// Response type for [`Client::status_get_dump_info`](super::Client::status_get_dump_info). + #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] + pub struct StatusGetDumpInfoResponse { + pub code: u16, + pub message: String, + + pub id: i64, + pub timestamp: String, + } +} diff --git a/src/raw/response/mod.rs b/src/raw/response/mod.rs index 424b816..6f77ba6 100644 --- a/src/raw/response/mod.rs +++ b/src/raw/response/mod.rs @@ -9,7 +9,6 @@ use attohttpc::Response; use serde::de::DeserializeOwned; use serde::Deserialize; -use serde::Serialize; use crate::Error; @@ -17,6 +16,7 @@ use crate::Error; pub mod art; pub mod core; pub mod metadata; +pub mod misc; pub mod playlists; pub mod popularity; pub mod recommendations; @@ -29,6 +29,7 @@ pub mod statistics; pub use crate::raw::response::art::*; pub use crate::raw::response::core::*; pub use crate::raw::response::metadata::*; +pub use crate::raw::response::misc::*; pub use crate::raw::response::playlists::*; pub use crate::raw::response::popularity::*; pub use crate::raw::response::recommendations::*; @@ -132,17 +133,3 @@ macro_rules! response_type { // Let the childrens access the macro pub(super) use response_type; - -// --------- status/get-dump-info - -response_type! { - /// Response type for [`Client::status_get_dump_info`](super::Client::status_get_dump_info). - #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] - pub struct StatusGetDumpInfoResponse { - pub code: u16, - pub message: String, - - pub id: i64, - pub timestamp: String, - } -} From 6da2c0c4863572389644f8bc0c176838c3d56db5 Mon Sep 17 00:00:00 2001 From: RustyNova Date: Tue, 11 Feb 2025 15:15:47 +0000 Subject: [PATCH 13/13] refactor: reformating and removed extra comments --- src/raw/response/art/mod.rs | 2 +- src/raw/response/metadata/mod.rs | 2 +- src/raw/response/popularity/mod.rs | 2 +- src/raw/response/recommendations/mod.rs | 2 +- src/raw/response/recordings/mod.rs | 2 +- src/raw/response/settings/mod.rs | 2 +- src/raw/response/social/mod.rs | 3 --- src/raw/response/statistics/mod.rs | 3 +-- 8 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/raw/response/art/mod.rs b/src/raw/response/art/mod.rs index 4be253b..784fa9b 100644 --- a/src/raw/response/art/mod.rs +++ b/src/raw/response/art/mod.rs @@ -1,3 +1,3 @@ //TODO: https://listenbrainz.readthedocs.io/en/latest/users/api/art.html // Currently no api responses have been made for this page. -// The header comments will be made as needed \ No newline at end of file +// The header comments will be made as needed diff --git a/src/raw/response/metadata/mod.rs b/src/raw/response/metadata/mod.rs index fb6977d..17fa84c 100644 --- a/src/raw/response/metadata/mod.rs +++ b/src/raw/response/metadata/mod.rs @@ -1,3 +1,3 @@ //TODO: https://listenbrainz.readthedocs.io/en/latest/users/api/metadata.html // Currently no api responses have been made for this page. -// The header comments will be made as needed \ No newline at end of file +// The header comments will be made as needed diff --git a/src/raw/response/popularity/mod.rs b/src/raw/response/popularity/mod.rs index fe6217f..e0d9f31 100644 --- a/src/raw/response/popularity/mod.rs +++ b/src/raw/response/popularity/mod.rs @@ -1,3 +1,3 @@ //TODO: https://listenbrainz.readthedocs.io/en/latest/users/api/popularity.html // Currently no api responses have been made for this page. -// The header comments will be made as needed \ No newline at end of file +// The header comments will be made as needed diff --git a/src/raw/response/recommendations/mod.rs b/src/raw/response/recommendations/mod.rs index 30c6bd2..66ca6cf 100644 --- a/src/raw/response/recommendations/mod.rs +++ b/src/raw/response/recommendations/mod.rs @@ -1,3 +1,3 @@ //TODO: https://listenbrainz.readthedocs.io/en/latest/users/api/recommendation.html // Currently no api responses have been made for this page. -// The header comments will be made as needed \ No newline at end of file +// The header comments will be made as needed diff --git a/src/raw/response/recordings/mod.rs b/src/raw/response/recordings/mod.rs index 77f1d51..c7a33be 100644 --- a/src/raw/response/recordings/mod.rs +++ b/src/raw/response/recordings/mod.rs @@ -1,3 +1,3 @@ //TODO: https://listenbrainz.readthedocs.io/en/latest/users/api/recordings.html // Currently no api responses have been made for this page. -// The header comments will be made as needed \ No newline at end of file +// The header comments will be made as needed diff --git a/src/raw/response/settings/mod.rs b/src/raw/response/settings/mod.rs index 95d0c03..47224ef 100644 --- a/src/raw/response/settings/mod.rs +++ b/src/raw/response/settings/mod.rs @@ -1,3 +1,3 @@ //TODO: https://listenbrainz.readthedocs.io/en/latest/users/api/settings.html // Currently no api responses have been made for this page. -// The header comments will be made as needed \ No newline at end of file +// The header comments will be made as needed diff --git a/src/raw/response/social/mod.rs b/src/raw/response/social/mod.rs index dc99d67..6135edd 100644 --- a/src/raw/response/social/mod.rs +++ b/src/raw/response/social/mod.rs @@ -1,5 +1,3 @@ -// --------- user/{user_name}/followers - use serde::Deserialize; use serde::Serialize; @@ -50,4 +48,3 @@ response_type! { pub status: String, } } - diff --git a/src/raw/response/statistics/mod.rs b/src/raw/response/statistics/mod.rs index d05a5eb..1948d7c 100644 --- a/src/raw/response/statistics/mod.rs +++ b/src/raw/response/statistics/mod.rs @@ -49,7 +49,6 @@ response_type! { } } - /// Type of the [`StatsUserReleasesResponse::payload`] field. #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] pub struct StatsUserReleasesPayload { @@ -271,4 +270,4 @@ pub struct StatsSitewideArtistsArtist { pub artist_mbids: Option>, pub artist_name: String, pub listen_count: u64, -} \ No newline at end of file +}