use clap::{Parser, Subcommand};
use modlist::{
config::Cfg,
db::{config_get_current_list, lists_get, lists_get_all_ids},
download, export, get_current_list, import, list_add, list_change, list_remove, list_version,
mod_add, mod_remove, update, IDSelector, List, Modloader,
};
//TODO implement remote sql db
//TODO make default list optional
#[derive(Parser)]
#[command(author, version, about)]
struct Cli {
#[command(subcommand)]
command: Commands,
/// config file path
#[arg(short, long)]
config: Option<String>,
}
#[derive(Subcommand)]
enum Commands {
r#Mod {
#[command(subcommand)]
command: ModCommands,
},
List {
#[command(subcommand)]
command: ListCommands,
},
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,
},
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,
},
Import {
#[arg(short, long)]
file: Option<String>,
/// directly download imported mods
#[arg(short, long)]
download: bool,
},
Export {
/// the list you want to export
list: Option<String>,
},
}
#[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<String>,
},
Remove {
/// id, name or title of the mod
id: String,
/// optional List selection, else default list will be used
#[arg(short, long)]
list: Option<String>,
},
}
#[derive(Subcommand)]
enum ListCommands {
Add {
/// list id
id: String,
directory: String,
modloader: Option<String>,
version: Option<String>,
},
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).unwrap();
match cli.command {
Commands::Mod { command } => {
match command {
#[allow(unused_variables)]
ModCommands::Add {
id,
version,
list,
download,
lock,
} => {
let listf = match list {
Some(list) => lists_get(config.clone(), list).unwrap(),
None => lists_get(
config.clone(),
config_get_current_list(config.clone()).unwrap(),
)
.unwrap(),
};
let marked_id = match version {
true => IDSelector::VersionID(id),
false => IDSelector::ModificationID(id),
};
mod_add(config, vec![marked_id], listf, download, lock).await
}
ModCommands::Remove { id, list } => {
//TODO add output
//TODO add success even if no file found
let listf = match list {
Some(list) => lists_get(config.clone(), list).unwrap(),
None => lists_get(
config.clone(),
config_get_current_list(config.clone()).unwrap(),
)
.unwrap(),
};
mod_remove(config, &id, listf)
}
}
}
Commands::List { command } => {
match command {
ListCommands::Add {
id,
directory,
modloader,
version,
} => {
let ml = match modloader {
Some(ml) => Modloader::from(&ml).unwrap(),
None => config.clone().defaults.modloader,
};
let ver = match version {
Some(ver) => ver,
//TODO get latest version
//TODO impl config for specific version or latest or latest snap
None => "1.19.4".to_string(),
};
list_add(config, id, ver, ml, directory)
}
ListCommands::Remove { id } => list_remove(config, id),
ListCommands::List => {
todo!()
}
ListCommands::Change { id } => list_change(config, id),
ListCommands::Version {
id,
version,
download,
remove,
} => list_version(config, id, version, download, remove).await,
}
}
//TODO a add specific list
Commands::Update {
all,
download,
clean,
remove,
} => {
let mut liststack: Vec<List> = vec![];
if all {
let list_ids = lists_get_all_ids(config.clone()).unwrap();
for id in list_ids {
liststack.push(lists_get(config.clone(), id).unwrap());
}
} else {
let current = get_current_list(config.clone()).unwrap();
println!("Update list {}:", current.id);
liststack.push(current)
}
update(config, liststack, clean, download, remove).await
}
//TODO add specific list
Commands::Download { all, clean, remove } => download(config, all, 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),
}
.unwrap();
}