use serde::de::DeserializeOwned;
use crate::{
games::{get_game_by_steam_app_id_url, get_gameinfo_by_game_id_url, GameInfo},
images::{
get_images_by_game_id_url, get_images_by_game_ids_url, get_images_by_platform_id_url,
get_images_by_platform_ids_url, Image, InnerImagesMultipleIdsResponse,
InnerImagesSingleIdResponse,
},
query_parameters::{Platform, QueryType},
response::{response_to_result, response_to_result_flat, SteamGridDbResult},
search::{get_search_url, InnerSearchResult, SearchResult},
steam_static::SteamStaticUrls,
};
pub struct Client {
auth_key: String,
base_url: String,
#[cfg(feature = "async")]
client: reqwest::Client,
#[cfg(feature = "blocking")]
client: reqwest::blocking::Client,
}
impl Client {
pub fn new<S>(auth_key: S) -> Self
where
S: Into<String>,
{
let default_base_url = "https://www.steamgriddb.com/api/v2";
#[cfg(feature = "async")]
let client = reqwest::Client::new();
#[cfg(feature = "blocking")]
let client = reqwest::blocking::Client::new();
Self {
auth_key: auth_key.into(),
base_url: default_base_url.to_owned(),
client,
}
}
pub fn set_base_url<S>(&mut self, base_url: S)
where
S: Into<String>,
{
self.base_url = base_url.into();
}
pub fn base_url(&'_ self) -> &'_ str {
self.base_url.as_str()
}
pub fn get_auth_key(&self) -> &'_ str {
self.auth_key.as_str()
}
pub fn set_auth_key<S>(&mut self, auth_key: S)
where
S: Into<String>,
{
self.auth_key = auth_key.into();
}
#[cfg(feature = "async")]
pub async fn get_images_for_id(
&self,
game_id: usize,
query: &QueryType<'_>,
) -> Result<Vec<Image>, Box<dyn std::error::Error>> {
let url = get_images_by_game_id_url(self.base_url.as_str(), game_id, query);
let response = self
.make_request::<InnerImagesSingleIdResponse>(url.as_str())
.await?;
Ok(response_to_result(response)?)
}
#[cfg(feature = "blocking")]
pub fn get_images_for_id(
&self,
game_id: usize,
query: &QueryType<'_>,
) -> Result<Vec<Image>, Box<dyn std::error::Error>> {
let url = get_images_by_game_id_url(self.base_url.as_str(), game_id, query);
let response = self.make_request::<InnerImagesSingleIdResponse>(url.as_str())?;
Ok(response_to_result(response)?)
}
#[cfg(feature = "async")]
pub async fn get_images_for_ids(
&self,
game_id: &[usize],
query: &QueryType<'_>,
) -> Result<Vec<SteamGridDbResult<Image>>, Box<dyn std::error::Error>> {
if game_id.is_empty() {
return Ok(Vec::new());
}
if game_id.len() == 1 {
let single_result = self.get_images_for_id(game_id[0], query).await?;
if !single_result.is_empty() {
return Ok(vec![SteamGridDbResult::Ok(single_result[0].clone())]);
}
}
let url = get_images_by_game_ids_url(self.base_url.as_str(), game_id, query);
let resposse = self
.make_request::<InnerImagesMultipleIdsResponse>(url.as_str())
.await?;
Ok(response_to_result_flat(resposse)?)
}
#[cfg(feature = "blocking")]
pub fn get_images_for_ids(
&self,
game_id: &[usize],
query: &QueryType<'_>,
) -> Result<Vec<SteamGridDbResult<Image>>, Box<dyn std::error::Error>> {
if game_id.is_empty() {
return Ok(Vec::new());
}
if game_id.len() == 1 {
let single_result = self.get_images_for_id(game_id[0], query)?;
if !single_result.is_empty() {
return Ok(vec![SteamGridDbResult::Ok(single_result[0].clone())]);
}
}
let url = get_images_by_game_ids_url(self.base_url.as_str(), game_id, query);
let resposse = self.make_request::<InnerImagesMultipleIdsResponse>(url.as_str())?;
Ok(response_to_result_flat(resposse)?)
}
#[cfg(feature = "async")]
pub async fn search(
&self,
query: &str,
) -> Result<Vec<SearchResult>, Box<dyn std::error::Error>> {
let url = get_search_url(self.base_url.as_str(), query);
let response = self.make_request::<InnerSearchResult>(url.as_str()).await?;
Ok(response_to_result(response)?)
}
#[cfg(feature = "blocking")]
pub fn search(&self, query: &str) -> Result<Vec<SearchResult>, Box<dyn std::error::Error>> {
let url = get_search_url(self.base_url.as_str(), query);
let response = self.make_request::<InnerSearchResult>(url.as_str())?;
Ok(response_to_result(response)?)
}
#[cfg(feature = "async")]
pub async fn get_images_for_platform_id(
&self,
platform: &Platform,
game_id: &str,
qeury: &QueryType<'_>,
) -> Result<Vec<Image>, Box<dyn std::error::Error>> {
let url = get_images_by_platform_id_url(self.base_url.as_str(), platform, game_id, qeury);
let response = self
.make_request::<InnerImagesSingleIdResponse>(url.as_str())
.await?;
Ok(response_to_result(response)?)
}
#[cfg(feature = "blocking")]
pub fn get_images_for_platform_id(
&self,
platform: &Platform,
game_id: &str,
qeury: &QueryType<'_>,
) -> Result<Vec<Image>, Box<dyn std::error::Error>> {
let url = get_images_by_platform_id_url(self.base_url.as_str(), platform, game_id, qeury);
let response = self.make_request::<InnerImagesSingleIdResponse>(url.as_str())?;
Ok(response_to_result(response)?)
}
#[cfg(feature = "async")]
pub async fn get_images_for_platform_ids(
&self,
platform: &Platform,
game_id: &[&str],
qeury: &QueryType<'_>,
) -> Result<Vec<SteamGridDbResult<Image>>, Box<dyn std::error::Error>> {
let url = get_images_by_platform_ids_url(self.base_url.as_str(), platform, game_id, qeury);
let resposse = self
.make_request::<InnerImagesMultipleIdsResponse>(url.as_str())
.await?;
Ok(response_to_result_flat(resposse)?)
}
#[cfg(feature = "blocking")]
pub fn get_images_for_platform_ids(
&self,
platform: &Platform,
game_id: &[&str],
qeury: &QueryType<'_>,
) -> Result<Vec<SteamGridDbResult<Image>>, Box<dyn std::error::Error>> {
let url = get_images_by_platform_ids_url(self.base_url.as_str(), platform, game_id, qeury);
let resposse = self.make_request::<InnerImagesMultipleIdsResponse>(url.as_str())?;
Ok(response_to_result_flat(resposse)?)
}
#[cfg(feature = "async")]
pub async fn get_game_info_for_id(
&self,
game_id: usize,
) -> Result<GameInfo, Box<dyn std::error::Error>> {
let url = get_gameinfo_by_game_id_url(self.base_url.as_str(), game_id);
let response = self.make_request::<GameInfo>(url.as_str()).await?;
Ok(response)
}
#[cfg(feature = "blocking")]
pub fn get_game_info_for_id(
&self,
game_id: usize,
) -> Result<GameInfo, Box<dyn std::error::Error>> {
let url = get_gameinfo_by_game_id_url(self.base_url.as_str(), game_id);
let response = self.make_request::<GameInfo>(url.as_str())?;
Ok(response)
}
#[cfg(feature = "async")]
pub async fn get_game_by_steam_app_id(
&self,
steam_app_id: usize,
) -> Result<GameInfo, Box<dyn std::error::Error>> {
let url = get_game_by_steam_app_id_url(self.base_url.as_str(), steam_app_id);
let response = self.make_request::<GameInfo>(url.as_str()).await?;
Ok(response)
}
#[cfg(feature = "blocking")]
pub fn get_game_by_steam_app_id(
&self,
steam_app_id: usize,
) -> Result<GameInfo, Box<dyn std::error::Error>> {
let url = get_game_by_steam_app_id_url(self.base_url.as_str(), steam_app_id);
let response = self.make_request::<GameInfo>(url.as_str())?;
Ok(response)
}
#[cfg(feature = "async")]
async fn make_request<'de, T>(&self, url: &str) -> Result<T, Box<dyn std::error::Error>>
where
T: DeserializeOwned,
{
Ok(self
.client
.get(url)
.bearer_auth(self.auth_key.as_str())
.send()
.await?
.json::<T>()
.await?)
}
#[cfg(feature = "blocking")]
fn make_request<'de, T>(&self, url: &str) -> Result<T, Box<dyn std::error::Error>>
where
T: DeserializeOwned,
{
Ok(self
.client
.get(url)
.bearer_auth(self.auth_key.as_str())
.send()?
.json::<T>()?)
}
pub fn get_official_steam_images_static(steam_app_id: &str) -> SteamStaticUrls {
SteamStaticUrls::new(steam_app_id)
}
pub fn get_official_steam_images(&self, steam_app_id: &str) -> SteamStaticUrls {
Self::get_official_steam_images_static(steam_app_id)
}
}