use crate::modrinth; use crate::pack; use inquire::Select; use serde::{Deserialize, Serialize}; use std::{ fmt::{Display, Formatter}, fs, }; #[derive(Serialize, Deserialize)] pub struct Config { pub info: Info, pub mods: Vec, } #[derive(Serialize, Deserialize)] pub struct Mod { pub id: String, pub version_id: String, } #[derive(Serialize, Deserialize)] pub struct Info { loader: Modloader, minecraft_version: String, } #[derive(Serialize, Deserialize, Debug, Clone, Copy)] pub enum Modloader { Fabric, Quilt, Forge, Neoforge, } impl Modloader { const VARIANTS: &'static [Modloader] = &[Self::Fabric, Self::Quilt, Self::Forge, Self::Neoforge]; } impl Display for Modloader { fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> { write!(f, "{self:?}") } } impl Config { pub fn get() -> Self { let pack_string = fs::read_to_string(".packium.toml").unwrap(); toml::from_str(&pack_string).unwrap() } pub async fn mods(&self) -> Vec { modrinth::get_multiple_project(self.mods.iter().map(|x| x.id.clone()).collect()) .await .unwrap() } pub async fn init() { println!("Fetching Minecraft information..."); let versions = modrinth::get_minecraft_versions().await.unwrap(); let versions = versions .iter() .filter(|x| x.version_type == "release".to_string()) .map(|x| &x.version) .collect(); let modloader = Select::new("Modloader?", Modloader::VARIANTS.to_vec()) .prompt() .unwrap(); let version = Select::new("Minecraft version?", versions) .prompt() .unwrap(); let pack = Config { info: Info { minecraft_version: version.to_owned(), loader: modloader, }, mods: vec![], }; let pack_toml = toml::to_string_pretty(&pack).unwrap(); std::fs::write(".packium.toml", pack_toml).unwrap(); } pub async fn add(name: &String) { let mut config = Self::get(); let mods = modrinth::search_projects( name.to_owned(), &config.info.minecraft_version, &config.info.loader.to_string().to_lowercase(), ) .await .unwrap(); let project = Select::new("Choose a mod", mods).prompt().unwrap(); let versions = modrinth::get_project_versions( &project.project_id, &config.info.minecraft_version, &config.info.loader.to_string().to_lowercase(), ) .await .unwrap(); let version = versions.get(0).unwrap(); config.mods.push(Mod { id: project.project_id.clone(), version_id: version.id.clone(), }); let config_toml = toml::to_string_pretty(&config).unwrap(); std::fs::write(".packium.toml", config_toml).unwrap(); } pub async fn remove() { let mut config = Self::get(); let mods = config.mods().await; let project = Select::new("Choose a mod to remove", mods) .prompt() .unwrap(); config.mods.retain(|x| x.id != project.id); let config_toml = toml::to_string_pretty(&config).unwrap(); std::fs::write(".packium.toml", config_toml).unwrap(); } }