use clap::{Parser, Subcommand}; pub mod apis; pub mod cache; pub mod commands; pub mod config; pub mod db; pub mod error; pub mod files; pub mod data; use commands::{download::download, io::{export, import}, list, modification::{mod_add, mod_remove}, update::update}; use config::Cfg; use data::{gameversion::VersionLevel, list::List, modification::{AddMod, IDSelector}, modloader::Modloader}; pub use data::{STYLE_BAR_POS, STYLE_MESSAGE, STYLE_SPINNER, STYLE_BAR_BYTE, STYLE_OPERATION, PROGRESS_CHARS}; use db::{config_get_current_list, lists_get, lists_get_all_ids}; use error::MLE; #[derive(Parser)] #[command(author, version, about)] struct Cli { #[command(subcommand)] command: Commands, /// config file path #[arg(short, long)] config: Option, } #[derive(Subcommand)] enum Commands { r#Mod { #[command(subcommand)] command: ModCommands, }, List { #[command(subcommand)] command: ListCommands, /// Force `GameVersion` update #[arg(long)] force_gameupdate: bool, }, Download { /// download all lists #[arg(short, long)] all: bool, /// clean all mods before downloading them #[arg(short, long)] clean: bool, /// remove disabled versions #[arg(short, long)] remove: bool, /// optional List selection, else default list will be used #[arg(short, long)] list: Option, }, Update { /// download all lists #[arg(short, long)] all: bool, /// directly download updated mods #[arg(short, long)] download: bool, /// clean all mods before downloading them #[arg(short, long)] clean: bool, /// delete disabled versions #[arg(short, long)] remove: bool, /// optional List selection, else default list will be used #[arg(short, long)] list: Option, }, Import { #[arg(short, long)] file: Option, /// directly download imported mods #[arg(short, long)] download: bool, }, Export { /// the list you want to export list: Option, }, Test, } #[derive(Subcommand)] enum ModCommands { Add { /// id of the mod/version id: String, /// set id mode to version #[arg(short, long)] version: bool, /// directly download the mod #[arg(short, long)] download: bool, /// lock the version added #[arg(/* short , */long)] lock: bool, /// optional List selection, else default list will be used #[arg(short, long)] list: Option, }, Remove { /// id, name or title of the mod id: String, /// optional List selection, else default list will be used #[arg(short, long)] list: Option, }, } #[derive(Subcommand)] enum ListCommands { Add { /// list id id: String, directory: String, modloader: Option, version: Option, }, Remove { /// id, name or title of the list id: String, }, List, Change { /// id of the list to change to id: String, }, Version { /// list id id: String, /// desired minecraft version version: String, /// directly download updated mods #[arg(long, short)] download: bool, /// delete disabled versions #[arg(short, long)] remove: bool, }, } #[tokio::main] async fn main() { let cli = Cli::parse(); let config = Cfg::init(cli.config).await.unwrap(); match cli.command { Commands::Mod { command } => handle_mod(config, command).await, Commands::List { command, force_gameupdate, } => handle_list(config, command, force_gameupdate).await, Commands::Update { all, download, clean, remove, list, } => { let mut liststack: Vec = vec![]; if all { let list_ids = lists_get_all_ids(&config).unwrap(); for id in list_ids { liststack.push(lists_get(&config, &id).unwrap()); } } else { let current = match list { Some(l) => lists_get(&config, &l).unwrap(), None => List::get_current_list(&config).unwrap(), }; liststack.push(current); } update(&config, liststack, clean, download, remove).await } Commands::Download { all, clean, remove, list, } => { let mut liststack: Vec = vec![]; if all { let list_ids = lists_get_all_ids(&config).unwrap(); for id in list_ids { liststack.push(lists_get(&config, &id).unwrap()); } } else { let current = match list { Some(l) => lists_get(&config, &l).unwrap(), None => List::get_current_list(&config).unwrap(), }; liststack.push(current); } download(&config, liststack, clean, remove).await } Commands::Import { file, download } => { let filestr: String = match file { Some(args) => args, None => dirs::home_dir() .unwrap() .join("mlexport.toml") .into_os_string() .into_string() .unwrap(), }; import(&config, &filestr, download).await } Commands::Export { list } => export(&config, list), Commands::Test => Ok(()), } .unwrap(); } async fn handle_mod(config: Cfg, command: ModCommands) -> MLE<()> { match command { ModCommands::Add { id, version, list, download, lock, } => { let listf = match list { Some(list) => lists_get(&config, &list).unwrap(), None => lists_get( &config, &config_get_current_list(&config).unwrap(), ) .unwrap(), }; let marked_id = if version { IDSelector::VersionID(id) } else { IDSelector::ModificationID(id) }; let add_id = AddMod { id: marked_id, set_version: lock, }; mod_add(&config, vec![add_id], listf, download).await } ModCommands::Remove { id, list } => { let listf = match list { Some(list) => lists_get(&config, &list).unwrap(), None => lists_get( &config, &config_get_current_list(&config).unwrap(), ) .unwrap(), }; mod_remove(&config, &id, &listf) } } } async fn handle_list( config: Cfg, command: ListCommands, force_gameupdate: bool, ) -> MLE<()> { match command { ListCommands::Add { id, directory, modloader, version, } => { let ml = match modloader { Some(ml) => Modloader::from(&ml).unwrap(), None => config.defaults.modloader.clone(), }; let versions_path = &config.versions; let ver = match version { Some(ver) => VersionLevel::from(&ver) .get(versions_path, force_gameupdate) .await .unwrap(), None => config .defaults .version .clone() .get(versions_path, force_gameupdate) .await .unwrap(), }; list::add(&config, &id, &ver, &ml, &directory) } ListCommands::Remove { id } => list::remove(&config, &id), ListCommands::List => list::list(&config), ListCommands::Change { id } => list::change(&config, &id), ListCommands::Version { id, version, download, remove, } => list::version(&config, &id, version, download, remove).await, } }