use super::user::*; use super::Error; use async_trait::async_trait; use serde::{Deserialize, Serialize}; use std::collections::HashMap; #[derive(Debug, Deserialize, Serialize, Clone)] pub struct Client { client_id: String, client_secret: String, client_token: String, base_url: String, } #[derive(Debug, Deserialize, Serialize, Clone)] pub struct AccessToken { token_type: String, expires_in: u64, access_token: String, } impl<'a> Client { pub async fn new, CS: Into>( client_id: CI, client_secret: CS, ) -> Result { let mut client = Client { client_id: client_id.into(), client_secret: client_secret.into(), base_url: "https://osu.ppy.sh/api/v2".to_string(), client_token: "".to_string(), }; client.refresh_token().await.unwrap(); Ok(client) } async fn get(&mut self, url: String, params: T) -> Result where T: Into> { let cli = reqwest::Client::new(); let parms = params.into(); let resp = match cli.get(&format!("{}{}", &self.base_url, &url).to_string()) .bearer_auth(&self.client_token).query(&parms).send().await { Ok(v) => { if v.status().is_client_error() { self.refresh_token().await.unwrap(); cli.get(&format!("{}{}", &self.base_url, &url).to_string()) .bearer_auth(&self.client_token).query(&parms).send().await.unwrap() } else { v } }, Err(why) => {return Err(Error::NotAuthenticated(why.to_string()))}, }; Ok(resp) } async fn refresh_token(&mut self) -> Result<(), Error> { let client = reqwest::Client::new(); let mut data = HashMap::new(); data.insert("client_id", self.client_id.clone()); data.insert("client_secret", self.client_secret.clone()); data.insert("grant_type", "client_credentials".to_string()); data.insert("scope", "public".to_string()); let token = match client .post("https://osu.ppy.sh/oauth/token") .json(&data) .send() .await { Ok(a) => a, Err(why) => return Err(Error::NotAuthenticated(why.to_string())), } .json::() .await.unwrap(); self.client_token = token.access_token; Ok(()) } } #[async_trait] impl UserMethods for Client { async fn get_user<'a>(&'a mut self, id: u64, m: String) -> Result, Error> { let resp = self .get(format!("/users/{}/{}", id, m), None) .await .unwrap(); let user = resp.json::().await.unwrap(); Ok(Box::new(user)) //Ok(()) } async fn search_user<'a>(&'a mut self, name: String) -> Result, Error> { let paras = [("mode", "user"), ("query", &name)]; let resp = self .get("/search".to_string(), ¶s[..]) .await .unwrap(); let users = resp.json::().await.unwrap(); Ok(Box::new(users)) } } //fn get()