use crate::official::endpoints as e;
use crate::official::request::{
CategoriesParams, FeaturedProjectsBody, GamesDelegate, GamesParams, GamesStream,
PaginatedDataResponse, ProjectFilesDelegate, ProjectFilesParams, ProjectFilesStream,
ProjectSearchDelegate, ProjectSearchParams, ProjectSearchStream,
};
use crate::official::types::{
Category, FeaturedProjects, Game, GameVersionType, GameVersions, Project, ProjectFile,
};
use crate::Error;
#[derive(Clone, Debug)]
pub struct Client {
inner: isahc::HttpClient,
base: url::Url,
}
#[derive(Clone, Debug)]
pub struct ClientOptions {
pub max_connections: usize,
}
#[allow(clippy::derivable_impls)]
impl Default for ClientOptions {
fn default() -> Self {
Self { max_connections: 0 }
}
}
impl Client {
pub fn new<U>(
base: U,
token: Option<String>,
options: Option<&ClientOptions>,
) -> Result<Self, Error>
where
U: AsRef<str>,
{
let mut builder = isahc::HttpClient::builder();
builder = builder.default_header("content-type", "application/json");
builder = builder.default_header("accept", "application/json");
if let Some(options) = options {
builder = builder.max_connections(options.max_connections);
}
if let Some(token) = token {
builder = builder.default_header("x-api-key", token);
}
let base = url::Url::parse(base.as_ref())?;
if base.cannot_be_a_base() {
Err(Error::BadBaseUrl)?;
}
Ok(Self {
inner: builder.build()?,
base,
})
}
pub async fn game(&self, game_id: i32) -> Result<Game, Error> {
e::game(&self.inner, &self.base, game_id)
.await
.map(|r| r.value.data)
}
pub async fn games(&self, params: &GamesParams) -> Result<PaginatedDataResponse<Game>, Error> {
e::games(&self.inner, &self.base, params)
.await
.map(|r| r.value)
}
pub fn games_iter<'cu, 'f>(&'cu self, params: GamesParams) -> GamesStream<'cu, 'f> {
GamesDelegate::new(&self.inner, &self.base, params).into()
}
pub async fn game_versions(&self, game_id: i32) -> Result<Vec<GameVersions>, Error> {
e::game_versions(&self.inner, &self.base, game_id)
.await
.map(|r| r.value.data)
}
pub async fn game_version_types(&self, game_id: i32) -> Result<Vec<GameVersionType>, Error> {
e::game_version_types(&self.inner, &self.base, game_id)
.await
.map(|r| r.value.data)
}
pub async fn categories(&self, params: &CategoriesParams) -> Result<Vec<Category>, Error> {
e::categories(&self.inner, &self.base, params)
.await
.map(|r| r.value.data)
}
pub async fn search_projects(
&self,
params: &ProjectSearchParams,
) -> Result<PaginatedDataResponse<Project>, Error> {
e::search_projects(&self.inner, &self.base, params)
.await
.map(|r| r.value)
}
pub fn search_projects_iter<'cu, 'f>(
&'cu self,
params: ProjectSearchParams,
) -> ProjectSearchStream<'cu, 'f> {
ProjectSearchDelegate::new(&self.inner, &self.base, params).into()
}
pub async fn project(&self, project_id: i32) -> Result<Project, Error> {
e::project(&self.inner, &self.base, project_id)
.await
.map(|r| r.value.data)
}
pub async fn projects<I>(&self, project_ids: I) -> Result<Vec<Project>, Error>
where
I: IntoIterator<Item = i32>,
{
e::projects(&self.inner, &self.base, project_ids)
.await
.map(|r| r.value.data)
}
pub async fn featured_projects(
&self,
body: &FeaturedProjectsBody,
) -> Result<FeaturedProjects, Error> {
e::featured_projects(&self.inner, &self.base, body)
.await
.map(|r| r.value.data)
}
pub async fn project_description(&self, project_id: i32) -> Result<String, Error> {
e::project_description(&self.inner, &self.base, project_id)
.await
.map(|r| r.value.data)
}
pub async fn project_file(&self, project_id: i32, file_id: i32) -> Result<ProjectFile, Error> {
e::project_file(&self.inner, &self.base, project_id, file_id)
.await
.map(|r| r.value.data)
}
pub async fn project_file_by_id(&self, file_id: i32) -> Result<ProjectFile, Error> {
e::project_files_by_ids(&self.inner, &self.base, [file_id])
.await
.map(|mut r| r.value.pop().unwrap())
}
pub async fn project_files(
&self,
project_id: i32,
params: &ProjectFilesParams,
) -> Result<PaginatedDataResponse<ProjectFile>, Error> {
e::project_files(&self.inner, &self.base, project_id, params)
.await
.map(|r| r.value)
}
pub fn project_files_iter<'cu, 'f>(
&'cu self,
project_id: i32,
params: ProjectFilesParams,
) -> ProjectFilesStream<'cu, 'f> {
ProjectFilesDelegate::new(&self.inner, &self.base, project_id, params).into()
}
pub async fn project_files_by_ids<I>(&self, file_ids: I) -> Result<Vec<ProjectFile>, Error>
where
I: IntoIterator<Item = i32>,
{
e::project_files_by_ids(&self.inner, &self.base, file_ids)
.await
.map(|r| r.value.data)
}
pub async fn project_file_changelog(
&self,
project_id: i32,
file_id: i32,
) -> Result<String, Error> {
e::project_file_changelog(&self.inner, &self.base, project_id, file_id)
.await
.map(|r| r.value.data)
}
pub async fn project_file_download_url(
&self,
project_id: i32,
file_id: i32,
) -> Result<String, Error> {
e::project_file_download_url(&self.inner, &self.base, project_id, file_id)
.await
.map(|r| r.value.data)
}
}