Added the ability to remove mods

This commit is contained in:
xeovalyte 2024-05-28 17:21:43 +02:00
parent d7c50ec8be
commit 6f6c78d3ff
No known key found for this signature in database
3 changed files with 77 additions and 23 deletions

View File

@ -1,5 +1,5 @@
use crate::modrinth; use crate::modrinth;
use colored::*; use crate::pack;
use inquire::Select; use inquire::Select;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::{ use std::{
@ -8,15 +8,15 @@ use std::{
}; };
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub struct Pack { pub struct Config {
info: Info, pub info: Info,
mods: Vec<Mod>, pub mods: Vec<Mod>,
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub struct Mod { pub struct Mod {
id: String, pub id: String,
version_id: String, pub version_id: String,
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
@ -44,13 +44,19 @@ impl Display for Modloader {
} }
} }
impl Pack { impl Config {
pub fn get() -> Self { pub fn get() -> Self {
let pack_string = fs::read_to_string(".packium.toml").unwrap(); let pack_string = fs::read_to_string(".packium.toml").unwrap();
toml::from_str(&pack_string).unwrap() toml::from_str(&pack_string).unwrap()
} }
pub async fn mods(&self) -> Vec<modrinth::Project> {
modrinth::get_multiple_project(self.mods.iter().map(|x| x.id.clone()).collect())
.await
.unwrap()
}
pub async fn init() { pub async fn init() {
println!("Fetching Minecraft information..."); println!("Fetching Minecraft information...");
@ -70,7 +76,7 @@ impl Pack {
.prompt() .prompt()
.unwrap(); .unwrap();
let pack = Pack { let pack = Config {
info: Info { info: Info {
minecraft_version: version.to_owned(), minecraft_version: version.to_owned(),
loader: modloader, loader: modloader,
@ -84,12 +90,12 @@ impl Pack {
} }
pub async fn add(name: &String) { pub async fn add(name: &String) {
let mut pack = Self::get(); let mut config = Self::get();
let mods = modrinth::search_projects( let mods = modrinth::search_projects(
name.to_owned(), name.to_owned(),
&pack.info.minecraft_version, &config.info.minecraft_version,
&pack.info.loader.to_string().to_lowercase(), &config.info.loader.to_string().to_lowercase(),
) )
.await .await
.unwrap(); .unwrap();
@ -98,21 +104,36 @@ impl Pack {
let versions = modrinth::get_project_versions( let versions = modrinth::get_project_versions(
&project.project_id, &project.project_id,
&pack.info.minecraft_version, &config.info.minecraft_version,
&pack.info.loader.to_string().to_lowercase(), &config.info.loader.to_string().to_lowercase(),
) )
.await .await
.unwrap(); .unwrap();
let version = versions.get(0).unwrap(); let version = versions.get(0).unwrap();
pack.mods.push(Mod { config.mods.push(Mod {
id: project.project_id.clone(), id: project.project_id.clone(),
version_id: version.id.clone(), version_id: version.id.clone(),
}); });
let pack_toml = toml::to_string_pretty(&pack).unwrap(); let config_toml = toml::to_string_pretty(&config).unwrap();
std::fs::write(".packium.toml", pack_toml).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();
} }
} }

View File

@ -1,4 +1,5 @@
mod cli; mod cli;
mod config;
mod modrinth; mod modrinth;
mod pack; mod pack;
@ -10,10 +11,13 @@ async fn main() {
match &args.command { match &args.command {
cli::Commands::Init => { cli::Commands::Init => {
pack::Pack::init().await; config::Config::init().await;
} }
cli::Commands::Add { name } => { cli::Commands::Add { name } => {
pack::Pack::add(name).await; config::Config::add(name).await;
}
cli::Commands::Remove => {
config::Config::remove().await;
} }
_ => (), _ => (),
}; };

View File

@ -1,5 +1,5 @@
use crate::config;
use core::fmt; use core::fmt;
use serde::Deserialize; use serde::Deserialize;
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
@ -11,13 +11,30 @@ pub struct MinecraftVersion {
} }
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
pub struct Mod { pub struct SearchProject {
pub title: String, pub title: String,
pub description: String, pub description: String,
pub project_id: String, pub project_id: String,
pub game_versions: Vec<String>,
pub versions: Vec<String>,
} }
impl fmt::Display for Mod { impl fmt::Display for SearchProject {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.title)
}
}
#[derive(Deserialize, Debug)]
pub struct Project {
pub title: String,
pub description: String,
pub id: String,
pub game_versions: Vec<String>,
pub versions: Vec<String>,
}
impl fmt::Display for Project {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.title) write!(f, "{}", self.title)
} }
@ -25,7 +42,7 @@ impl fmt::Display for Mod {
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
pub struct Search { pub struct Search {
hits: Vec<Mod>, hits: Vec<SearchProject>,
} }
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
@ -48,7 +65,7 @@ pub async fn search_projects(
query: String, query: String,
version: &String, version: &String,
loader: &String, loader: &String,
) -> Result<Vec<Mod>, reqwest::Error> { ) -> Result<Vec<SearchProject>, reqwest::Error> {
let url = format!("https://api.modrinth.com/v2/search?query={query}&facets=[[\"project_type:mod\"],[\"versions:{version}\"],[\"categories:{loader}\"]]"); let url = format!("https://api.modrinth.com/v2/search?query={query}&facets=[[\"project_type:mod\"],[\"versions:{version}\"],[\"categories:{loader}\"]]");
let response = reqwest::get(url).await?.json::<Search>().await?; let response = reqwest::get(url).await?.json::<Search>().await?;
@ -70,3 +87,15 @@ pub async fn get_project_versions(
Ok(response) Ok(response)
} }
pub async fn get_multiple_project(
project_ids: Vec<String>,
) -> Result<Vec<Project>, reqwest::Error> {
let ids = project_ids.join("\", \"");
let url = format!("https://api.modrinth.com/v2/projects?ids=[\"{ids}\"]");
let response = reqwest::get(url).await?.json::<Vec<Project>>().await?;
Ok(response)
}