use serde::{Deserialize, Serialize};
use std::{path::PathBuf, str::FromStr};
#[derive(Deserialize, Serialize, Debug, Default, Clone)]
pub struct Config {
#[serde(skip_serializing_if = "is_zero")]
#[serde(default)]
pub active_profile: usize,
#[serde(skip_serializing_if = "Vec::is_empty")]
#[serde(default)]
pub profiles: Vec<Profile>,
#[serde(skip_serializing_if = "is_zero")]
#[serde(default)]
pub active_modpack: usize,
#[serde(skip_serializing_if = "Vec::is_empty")]
#[serde(default)]
pub modpacks: Vec<Modpack>,
}
fn is_zero(n: &usize) -> bool {
*n == 0
}
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct Modpack {
pub name: String,
pub output_dir: PathBuf,
pub install_overrides: bool,
pub identifier: ModpackIdentifier,
}
#[derive(Deserialize, Serialize, Debug, Clone, PartialEq, Eq)]
pub enum ModpackIdentifier {
CurseForgeModpack(i32),
ModrinthModpack(String),
}
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct Profile {
pub name: String,
pub output_dir: PathBuf,
pub game_version: String,
pub mod_loader: ModLoader,
pub mods: Vec<Mod>,
}
impl Profile {
pub fn get_version(&self, check_game_version: bool) -> Option<&str> {
if check_game_version {
Some(&self.game_version)
} else {
None
}
}
pub fn get_loader(&self, check_mod_loader: bool) -> Option<ModLoader> {
if check_mod_loader {
Some(self.mod_loader)
} else {
None
}
}
}
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct Mod {
pub name: String,
pub identifier: ModIdentifier,
#[serde(skip_serializing_if = "is_true")]
#[serde(default = "get_true")]
pub check_game_version: bool,
#[serde(skip_serializing_if = "is_true")]
#[serde(default = "get_true")]
pub check_mod_loader: bool,
}
fn is_true(b: &bool) -> bool {
*b
}
fn get_true() -> bool {
true
}
#[derive(Deserialize, Serialize, Debug, Clone, PartialEq, Eq)]
pub enum ModIdentifier {
CurseForgeProject(i32),
ModrinthProject(String),
GitHubRepository((String, String)),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ModIdentifierRef<'a> {
CurseForgeProject(i32),
ModrinthProject(&'a str),
GitHubRepository((&'a str, &'a str)),
}
impl ModIdentifier {
pub fn as_ref(&self) -> ModIdentifierRef {
match self {
ModIdentifier::CurseForgeProject(v) => ModIdentifierRef::CurseForgeProject(*v),
ModIdentifier::ModrinthProject(v) => ModIdentifierRef::ModrinthProject(v),
ModIdentifier::GitHubRepository(v) => ModIdentifierRef::GitHubRepository((&v.0, &v.1)),
}
}
}
#[derive(Deserialize, Serialize, Debug, Clone, Copy, PartialEq, Eq, clap::ValueEnum)]
pub enum ModLoader {
Quilt,
Fabric,
Forge,
NeoForge,
}
#[derive(thiserror::Error, Debug, PartialEq, Eq)]
#[error("The given string is not a recognised mod loader")]
pub struct ModLoaderParseError;
impl FromStr for ModLoader {
type Err = ModLoaderParseError;
fn from_str(from: &str) -> Result<Self, Self::Err> {
match from.trim().to_lowercase().as_str() {
"quilt" => Ok(Self::Quilt),
"fabric" => Ok(Self::Fabric),
"forge" => Ok(Self::Forge),
"neoforge" => Ok(Self::NeoForge),
_ => Err(Self::Err {}),
}
}
}