summaryrefslogtreecommitdiff
path: root/src/client.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/client.rs')
-rw-r--r--src/client.rs133
1 files changed, 114 insertions, 19 deletions
diff --git a/src/client.rs b/src/client.rs
index 5c6858b..0699545 100644
--- a/src/client.rs
+++ b/src/client.rs
@@ -1,50 +1,145 @@
//! Deezer client.
-use std::error::Error;
+use std::fmt::Debug;
+use hyper::client::{Client, HttpConnector};
+use hyper::Uri;
use serde::Deserialize;
-/// A user.
+use crate::auth::AccessToken;
+use crate::errors::client::DeezerClientError;
+use crate::playlist::Playlist;
+use crate::user::{User, UserPlaylist, UserPlaylists};
+
+/// Deezer API error.
#[derive(Debug, Deserialize)]
-pub struct User
+pub struct DeezerError
{
- /// The user ID.
- pub id: u32,
+ /// Error type.
+ #[serde(rename = "type")]
+ pub err_type: String,
+
+ /// Error message.
+ pub message: String,
- /// The user name.
- pub name: String,
+ /// Error code.
+ pub code: u32,
+}
+
+#[derive(Debug, Deserialize)]
+struct ErrorResponseBody
+{
+ error: DeezerError,
}
/// Deezer client.
-#[derive(Default)]
pub struct DeezerClient
{
- client: reqwest::Client,
+ client: Client<HttpConnector>,
api_url: &'static str,
+ access_token: AccessToken,
}
impl DeezerClient
{
/// Creates a new Deezer client.
#[must_use]
- pub fn new() -> Self
+ pub fn new(access_token: AccessToken) -> Self
{
Self {
- client: reqwest::Client::new(),
- api_url: "https://api.deezer.com",
+ client: Client::new(),
+ api_url: "api.deezer.com",
+ access_token,
}
}
/// Returns the authenticated user.
- pub async fn get_me(&self) -> Result<User, Box<dyn Error + Send + Sync>>
+ ///
+ /// # Errors
+ /// Will return Err if either sending the request or parsing the response fails.
+ pub async fn get_me(&self) -> Result<User, DeezerClientError>
+ {
+ let response = self
+ .client
+ .get(self.build_endpoint_uri(&"user/me".to_string())?)
+ .await?;
+
+ let body_buf = &*hyper::body::to_bytes(response).await?;
+
+ let err_body_result: Result<ErrorResponseBody, _> =
+ serde_json::from_slice(body_buf);
+
+ if let Ok(err_body) = err_body_result {
+ return Err(DeezerClientError::ReceivedErrorResponse(err_body.error));
+ }
+
+ serde_json::from_slice(body_buf).map_err(DeezerClientError::ParseResponseFailed)
+ }
+
+ /// Returns the playlists of a user.
+ ///
+ /// # Errors
+ /// Will return Err if either sending the request or parsing the response fails.
+ pub async fn get_user_playlists(
+ &self,
+ user_id: u64,
+ ) -> Result<Vec<UserPlaylist>, DeezerClientError>
+ {
+ let response = self
+ .client
+ .get(self.build_endpoint_uri(&format!("user/{}/playlists", user_id))?)
+ .await?;
+
+ let body_buf = &*hyper::body::to_bytes(response).await?;
+
+ let err_body_result: Result<ErrorResponseBody, _> =
+ serde_json::from_slice(body_buf);
+
+ if let Ok(err_body) = err_body_result {
+ return Err(DeezerClientError::ReceivedErrorResponse(err_body.error));
+ }
+
+ let user_playlists: UserPlaylists = serde_json::from_slice(body_buf)
+ .map_err(DeezerClientError::ParseResponseFailed)?;
+
+ Ok(user_playlists.data)
+ }
+
+ /// Returns a playlist.
+ ///
+ /// # Errors
+ /// Will return Err if either sending the request or parsing the response fails.
+ pub async fn get_playlist(
+ &self,
+ playlist_id: u64,
+ ) -> Result<Playlist, DeezerClientError>
{
- let user = self
+ let response = self
.client
- .get(format!("{}/user/me", self.api_url))
- .send()
- .await?
- .json::<User>()
+ .get(self.build_endpoint_uri(&format!("playlist/{}", playlist_id))?)
.await?;
- Ok(user)
+ let body_buf = &*hyper::body::to_bytes(response).await?;
+
+ let err_body_result: Result<ErrorResponseBody, _> =
+ serde_json::from_slice(body_buf);
+
+ if let Ok(err_body) = err_body_result {
+ return Err(DeezerClientError::ReceivedErrorResponse(err_body.error));
+ }
+
+ serde_json::from_slice(body_buf).map_err(DeezerClientError::ParseResponseFailed)
+ }
+
+ fn build_endpoint_uri(&self, endpoint: &String) -> Result<Uri, DeezerClientError>
+ {
+ Uri::builder()
+ .scheme("http")
+ .authority(self.api_url)
+ .path_and_query(format!(
+ "/{}?access_token={}",
+ endpoint, self.access_token.access_token
+ ))
+ .build()
+ .map_err(|_| DeezerClientError::BuildAPIEndpointURIFailed)
}
}