use reqwest::Client as HttpClient;
use reqwest::ClientBuilder;
use reqwest::Url;
use serde::de::DeserializeOwned;
use super::ChampionPosition;
use super::GameMode;
use super::error::Error;
use crate::champion::Info;
use crate::champion::MetaEntry;
use crate::champion::Response;
use crate::champion::Summary;
const BASE_URL: &str = "https://lol-api-champion.op.gg";
#[derive(Debug, Clone)]
pub struct Client {
base_url: Url,
http: HttpClient,
}
impl Default for Client {
fn default() -> Self { Self { base_url: Url::parse(BASE_URL).unwrap(), http: Default::default() } }
}
impl Client {
pub fn new() -> Self { Self::default() }
pub fn builder() -> ClientBuilder { HttpClient::builder() }
pub async fn champion_meta(&self) -> Result<Response<Vec<MetaEntry>>, Error> {
self.get("api/meta/champions").await
}
pub async fn champion_list(&self, mode: GameMode) -> Result<Response<Vec<Summary>>, Error> {
let path = format!("/api/global/champions/{}", mode);
self.get(&path).await
}
pub async fn champion_info(
&self, mode: GameMode, champion_id: u32, position: ChampionPosition,
) -> Result<Response<Info>, Error> {
if !mode.allows_position(position) {
return Err(Error::InvalidModePosition { mode, position });
}
let path = format!("api/global/champions/{}/{}/{}", mode, champion_id, position);
self.get(&path).await
}
async fn get<T>(&self, path: &str) -> Result<T, Error>
where
T: DeserializeOwned,
{
let mut url = self.base_url.join(path).map_err(|err| Error::UrlConstruction(err.to_string()))?;
url.query_pairs_mut().append_pair("hl", "zh_CN");
let response = self.http.get(url).send().await?.error_for_status()?;
Ok(response.json::<T>().await?)
}
}