use oauth2::AccessToken;
use reqwest;
use serde::Serialize;
use crate::{
oauth::{Authenticated, OauthClient},
USER_URL,
};
use super::{error::UserApiError, requests::GetUserInformation, responses::User};
pub struct UserApiClient {
client: reqwest::Client,
access_token: String,
}
impl From<&AccessToken> for UserApiClient {
fn from(value: &AccessToken) -> Self {
Self {
client: reqwest::Client::new(),
access_token: value.secret().clone(),
}
}
}
impl From<&OauthClient<Authenticated>> for UserApiClient {
fn from(value: &OauthClient<Authenticated>) -> Self {
UserApiClient {
client: reqwest::Client::new(),
access_token: value.get_access_token().secret().clone(),
}
}
}
impl UserApiClient {
async fn get<T>(&self, query: &T) -> Result<String, UserApiError>
where
T: Serialize,
{
let response = self
.client
.get(format!("{}/@me", USER_URL))
.bearer_auth(&self.access_token)
.query(&query)
.send()
.await
.map_err(|err| UserApiError::new(format!("Failed get request: {}", err)))?;
handle_response(response).await
}
pub async fn get_my_user_information(
&self,
query: &GetUserInformation,
) -> Result<User, UserApiError> {
let response = self.get(query).await?;
let result: User = serde_json::from_str(response.as_str()).map_err(|err| {
UserApiError::new(format!("Failed to parse AnimeList result: {}", err))
})?;
Ok(result)
}
}
async fn handle_response(response: reqwest::Response) -> Result<String, UserApiError> {
match response.status() {
reqwest::StatusCode::OK => {
let content = response.text().await.map_err(|err| {
UserApiError::new(format!("Failed to get content from response: {}", err))
})?;
Ok(content)
}
_ => Err(UserApiError::new(format!(
"Did not recieve OK response: {}",
response.status()
))),
}
}