use crate::config::structs::{Config, ModpackIdentifier};
use ferinth::{
structures::project::{Project, ProjectType},
Ferinth,
};
use furse::{structures::mod_structs::Mod, Furse};
use reqwest::StatusCode;
type Result<T> = std::result::Result<T, Error>;
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error("Modpack is already added to profile")]
AlreadyAdded,
#[error("The provided modpack does not exist")]
DoesNotExist,
#[error("The project is not a modpack")]
NotAModpack,
#[error("Modrinth: {0}")]
ModrinthError(ferinth::Error),
#[error("CurseForge: {0}")]
CurseForgeError(furse::Error),
}
impl From<furse::Error> for Error {
fn from(err: furse::Error) -> Self {
if let furse::Error::ReqwestError(source) = &err {
if Some(StatusCode::NOT_FOUND) == source.status() {
Self::DoesNotExist
} else {
Self::CurseForgeError(err)
}
} else {
Self::CurseForgeError(err)
}
}
}
impl From<ferinth::Error> for Error {
fn from(err: ferinth::Error) -> Self {
if let ferinth::Error::ReqwestError(source) = &err {
if Some(StatusCode::NOT_FOUND) == source.status() {
Self::DoesNotExist
} else {
Self::ModrinthError(err)
}
} else {
Self::ModrinthError(err)
}
}
}
pub async fn curseforge(curseforge: &Furse, config: &Config, project_id: i32) -> Result<Mod> {
let project = curseforge.get_mod(project_id).await?;
if config.modpacks.iter().any(|modpack| {
modpack.name == project.name
|| ModpackIdentifier::CurseForgeModpack(project.id) == modpack.identifier
}) {
Err(Error::AlreadyAdded)
} else if !project.links.website_url.as_str().contains("modpacks") {
Err(Error::NotAModpack)
} else {
Ok(project)
}
}
pub async fn modrinth(modrinth: &Ferinth, config: &Config, project_id: &str) -> Result<Project> {
let project = modrinth.get_project(project_id).await?;
if config.modpacks.iter().any(|modpack| {
modpack.name == project.title
|| ModpackIdentifier::ModrinthModpack(project.id.clone()) == modpack.identifier
}) {
Err(Error::AlreadyAdded)
} else if project.project_type != ProjectType::Modpack {
Err(Error::NotAModpack)
} else {
Ok(project)
}
}