From 9d2817f721a489b41aa6c297bdf36e791063b185 Mon Sep 17 00:00:00 2001 From: Warren Hood Date: Wed, 14 Aug 2024 21:51:42 +0200 Subject: [PATCH] Improved metadata and error handling --- Cargo.lock | 7 ---- Cargo.toml | 1 - src/main.rs | 32 +++++----------- src/modpack.rs | 100 ++++++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 105 insertions(+), 35 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b1eb3d2..f0afaa8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -51,12 +51,6 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "anyhow" -version = "1.0.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" - [[package]] name = "clap" version = "4.5.15" @@ -141,7 +135,6 @@ checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" name = "mcmpmgr" version = "0.1.0" dependencies = [ - "anyhow", "clap", "serde", "toml", diff --git a/Cargo.toml b/Cargo.toml index b0be1dc..d8013de 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,6 @@ version = "0.1.0" edition = "2021" [dependencies] -anyhow = "1.0.86" clap = { version = "4.5.15", features = ["derive"] } serde = { version = "1.0.207", features = ["derive"] } toml = "0.8.19" diff --git a/src/main.rs b/src/main.rs index 3df1380..b5c53fb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,8 @@ mod modpack; use clap::{Parser, Subcommand}; -use std::path::PathBuf; +use modpack::{ModLoader, ModMeta, ModProvider, ModpackMeta}; +use std::{error::Error, path::PathBuf}; /// A Minecraft Modpack Manager #[derive(Parser)] @@ -23,7 +24,7 @@ enum Commands { }, } -fn main() -> anyhow::Result<()> { +fn main() -> Result<(), Box> { let cli = Cli::parse(); if let Some(command) = cli.command { @@ -33,35 +34,22 @@ fn main() -> anyhow::Result<()> { mc_version, modloader, } => { - let dir = if let Some(directory) = directory { - directory - } else { - std::env::current_dir() - .expect("You should have permissions to access the current directory") - }; - - let mc_modpack_meta = modpack::ModpackMeta { - mc_version: mc_version, - modloader: modloader, - mods: vec![], - }; - + let dir = directory.unwrap_or(std::env::current_dir()?); + let mc_modpack_meta = ModpackMeta::new(&mc_version, modloader); let modpack_meta_file_path = dir.clone().join(PathBuf::from("mcmodpack.toml")); - if modpack_meta_file_path.exists() { - anyhow::bail!( + return Err(format!( "mcmodpack.toml already exists at {}", modpack_meta_file_path.display() - ); + ) + .into()); } - if let Err(e) = std::fs::write( + std::fs::write( modpack_meta_file_path, toml::to_string(&mc_modpack_meta) .expect("MC Modpack Meta should be serializable"), - ) { - anyhow::bail!("Unable to initialize new MC modpack project at {}:\n{}", dir.display(), e); - }; + )?; println!("MC modpack project initialized at {}", dir.display()); } diff --git a/src/modpack.rs b/src/modpack.rs index bde885b..e6b6962 100644 --- a/src/modpack.rs +++ b/src/modpack.rs @@ -1,8 +1,72 @@ +use std::borrow::BorrowMut; + use serde::{Deserialize, Serialize}; -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize, PartialEq)] +pub enum ModProvider { + /// Get mods from CurseForge + CurseForge, + /// Get mods from Modrinth + Modrinth, + /// Get mods from anywhere on the internet. Note: A download url is needed for this + Raw, +} + +#[derive(Debug, Serialize, Deserialize, PartialEq)] pub struct ModMeta { - download_url: String, + mod_name: String, + version: String, + providers: Option>, + download_url: Option, +} + +#[derive(Debug, Serialize, Deserialize, PartialEq)] +struct ModMetaBuilder { + mod_name: String, + version: String, + providers: Option>, + download_url: Option, +} + +impl ModMeta { + pub fn new(mod_name: &str) -> Self { + Self { + mod_name: mod_name.into(), + ..Default::default() + } + } + + pub fn provider(mut self, provider: ModProvider) -> Self { + if let Some(providers) = self.providers.borrow_mut() { + if !providers.contains(&provider) { + providers.push(provider) + } + } else { + self.providers = Some(vec![provider]); + } + self + } + + pub fn url(mut self, download_url: &str) -> Self { + self.download_url = Some(download_url.into()); + self + } + + pub fn version(mut self, version_constraint: &str) -> Self { + self.version = version_constraint.into(); + self + } +} + +impl Default for ModMeta { + fn default() -> Self { + Self { + mod_name: Default::default(), + version: "*".into(), + providers: None, + download_url: Default::default(), + } + } } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -35,9 +99,34 @@ impl std::str::FromStr for ModLoader { #[derive(Debug, Serialize, Deserialize)] pub struct ModpackMeta { - pub mc_version: String, - pub modloader: ModLoader, - pub mods: Vec, + mc_version: String, + modloader: ModLoader, + mods: Vec, + default_providers: Vec, +} + +impl ModpackMeta { + pub fn new(mc_version: &str, modloader: ModLoader) -> Self { + Self { + mc_version: mc_version.into(), + modloader: modloader, + ..Default::default() + } + } + + pub fn provider(mut self, provider: ModProvider) -> Self { + if !self.default_providers.contains(&provider) { + self.default_providers.push(provider); + } + self + } + + pub fn add_mod(mut self, mod_meta: ModMeta) -> Self { + if !self.mods.contains(&mod_meta) { + self.mods.push(mod_meta); + } + self + } } impl std::default::Default for ModpackMeta { @@ -46,6 +135,7 @@ impl std::default::Default for ModpackMeta { mc_version: "1.20.1".into(), modloader: ModLoader::Forge, mods: Default::default(), + default_providers: vec![ModProvider::Modrinth], } } }