diff --git a/src/commands/build/mod.rs b/src/commands/build/mod.rs index 63dc225..6feaa46 100644 --- a/src/commands/build/mod.rs +++ b/src/commands/build/mod.rs @@ -3,15 +3,15 @@ use std::{path::PathBuf, time::Instant}; use anyhow::{anyhow, Context, Result}; use clap::{arg, value_parser, ArgMatches, Command}; use console::style; -use tokio::fs::{File, self}; +use tokio::fs::{self, File}; use crate::{create_http_client, downloadable::Downloadable, model::Server, util}; -pub mod serverjar; pub mod addons; -pub mod worlds; pub mod bootstrap; pub mod scripts; +pub mod serverjar; +pub mod worlds; pub fn cli() -> Command { Command::new("build") @@ -139,8 +139,10 @@ impl BuildContext { folder_path: Option<&str>, report_back: F, ) -> Result { - let file_name = dl.get_filename(&self.server, &self.http_client) - .await.with_context(|| format!("Getting filename of Downloadable: {dl:#?}"))?; + let file_name = dl + .get_filename(&self.server, &self.http_client) + .await + .with_context(|| format!("Getting filename of Downloadable: {dl:#?}"))?; let file_path = if let Some(path) = folder_path { self.output_dir.join(path) @@ -154,21 +156,23 @@ impl BuildContext { } else { report_back(ReportBackState::Downloading, &file_name); - let file = File::create(&file_path).await.with_context(|| format!( - "Failed to create output file: {}", - file_path.to_string_lossy() - ))?; + let file = File::create(&file_path).await.with_context(|| { + format!( + "Failed to create output file: {}", + file_path.to_string_lossy() + ) + })?; let result = util::download_with_progress( - file, - &file_name, - dl, - Some(&file_name), - &self.server, - &self.http_client, - ) - .await - .with_context(|| format!("Downloading Downloadable: {dl:#?}")); + file, + &file_name, + dl, + Some(&file_name), + &self.server, + &self.http_client, + ) + .await + .with_context(|| format!("Downloading Downloadable: {dl:#?}")); if result.is_err() { // try to remove file if errored diff --git a/src/commands/build/worlds.rs b/src/commands/build/worlds.rs index 38f23f1..419a9ad 100644 --- a/src/commands/build/worlds.rs +++ b/src/commands/build/worlds.rs @@ -24,31 +24,27 @@ impl BuildContext { for (idx, dp) in world.datapacks.iter().enumerate() { let path = format!("{name}/datapacks"); - self.downloadable( - dp, - Some(&path), - |state, file_name| { - match state { - ReportBackState::Skipped => { - println!( - " {:pad_len$}({:dp_len$}/{datapack_count}) Skipping : {}", - idx + 1, - "", - style(file_name).dim() - ); - } - ReportBackState::Downloaded => { - println!( - " {:pad_len$}({:dp_len$}/{datapack_count}) {} : {}", - idx + 1, - "", - style("Downloaded").green().bold(), - style(file_name).dim() - ); - } - ReportBackState::Downloading => {} + self.downloadable(dp, Some(&path), |state, file_name| match state { + ReportBackState::Skipped => { + println!( + " {:pad_len$}({:dp_len$}/{datapack_count}) Skipping : {}", + idx + 1, + "", + style(file_name).dim() + ); } - }).await?; + ReportBackState::Downloaded => { + println!( + " {:pad_len$}({:dp_len$}/{datapack_count}) {} : {}", + idx + 1, + "", + style("Downloaded").green().bold(), + style(file_name).dim() + ); + } + ReportBackState::Downloading => {} + }) + .await?; } } diff --git a/src/commands/eject.rs b/src/commands/eject.rs index 86e5602..7633024 100644 --- a/src/commands/eject.rs +++ b/src/commands/eject.rs @@ -1,9 +1,9 @@ use std::fs; -use anyhow::{Result, Context}; +use anyhow::{Context, Result}; use clap::Command; use console::style; -use dialoguer::{Input, theme::ColorfulTheme}; +use dialoguer::{theme::ColorfulTheme, Input}; use crate::model::Server; @@ -13,7 +13,8 @@ pub fn cli() -> Command { .about("Eject - remove everything related to mcman") } -pub async fn run() -> Result<()> { +#[allow(unused_must_use)] +pub fn run() -> Result<()> { let server = Server::load().context("Failed to load server.toml")?; if Input::with_theme(&ColorfulTheme::default()) @@ -21,11 +22,11 @@ pub async fn run() -> Result<()> { .default(String::new()) .interact_text()? == server.name { println!(" > {}", style("Deleting server.toml...").yellow()); - _ = fs::remove_file(server.path.join("server.toml"))?; + fs::remove_file(server.path.join("server.toml"))?; println!(" > {}", style("Deleting config/...").yellow()); - _ = fs::remove_dir_all(server.path.join("config")); + fs::remove_dir_all(server.path.join("config")); println!(" > {}", style("Deleting server/...").yellow()); - _ = fs::remove_dir_all(server.path.join("server"))?; + fs::remove_dir_all(server.path.join("server"))?; println!(" > Ejected successfully."); } else { println!(" > {}", style("Cancelled").green().bold()); diff --git a/src/commands/export/mrpack.rs b/src/commands/export/mrpack.rs index 51ed644..20e1d51 100644 --- a/src/commands/export/mrpack.rs +++ b/src/commands/export/mrpack.rs @@ -1,7 +1,7 @@ use std::path::PathBuf; use anyhow::{Context, Result}; -use clap::{arg, ArgMatches, Command, value_parser}; +use clap::{arg, value_parser, ArgMatches, Command}; use crate::{create_http_client, model::Server, util::mrpack::export_mrpack}; @@ -10,8 +10,8 @@ pub fn cli() -> Command { .about("Export as an mrpack") .arg( arg!([filename] "Export as filename") - .value_parser(value_parser!(PathBuf)) - .required(false) + .value_parser(value_parser!(PathBuf)) + .required(false), ) .arg(arg!(-v --version "Set the version ID of the mrpack")) } @@ -20,11 +20,13 @@ pub async fn run(matches: &ArgMatches) -> Result<()> { let server = Server::load().context("Failed to load server.toml")?; let http_client = create_http_client()?; - let s = server.name.clone().replace(|c: char| !c.is_alphanumeric(), ""); + let s = server + .name + .clone() + .replace(|c: char| !c.is_alphanumeric(), ""); - let default_output = PathBuf::from( - if s.is_empty() { "server".to_owned() } else { s } + ".mrpack" - ); + let default_output = + PathBuf::from(if s.is_empty() { "server".to_owned() } else { s } + ".mrpack"); let output_filename = matches .get_one::("filename") @@ -39,16 +41,17 @@ pub async fn run(matches: &ArgMatches) -> Result<()> { let version_id = matches.get_one::("version"); - let output_file = std::fs::File::create(output_filename) - .context("Creating mrpack output file")?; + let output_file = + std::fs::File::create(output_filename).context("Creating mrpack output file")?; export_mrpack( &http_client, &server, None, version_id.unwrap_or(&String::new()), - output_file - ).await?; + output_file, + ) + .await?; Ok(()) -} \ No newline at end of file +} diff --git a/src/commands/export/packwiz.rs b/src/commands/export/packwiz.rs index 521b723..7b7ad0a 100644 --- a/src/commands/export/packwiz.rs +++ b/src/commands/export/packwiz.rs @@ -1,9 +1,13 @@ use std::path::PathBuf; use anyhow::{Context, Result}; -use clap::{arg, ArgMatches, Command, value_parser}; +use clap::{arg, value_parser, ArgMatches, Command}; -use crate::{create_http_client, model::Server, util::packwiz::{export_packwiz, PackwizExportOptions}}; +use crate::{ + create_http_client, + model::Server, + util::packwiz::{export_packwiz, PackwizExportOptions}, +}; pub fn cli() -> Command { Command::new("packwiz") @@ -13,9 +17,7 @@ pub fn cli() -> Command { arg!(-o --output [FILE] "The output directory for the packwiz files") .value_parser(value_parser!(PathBuf)), ) - .arg( - arg!(--cfcdn "Use edge.forgecdn.net instead of metadata:curseforge"), - ) + .arg(arg!(--cfcdn "Use edge.forgecdn.net instead of metadata:curseforge")) } pub async fn run(matches: &ArgMatches) -> Result<()> { @@ -30,9 +32,13 @@ pub async fn run(matches: &ArgMatches) -> Result<()> { let cf_usecdn = matches.get_flag("cfcdn"); - export_packwiz(&output_dir, &http_client, &server, &PackwizExportOptions { - cf_usecdn - }).await?; + export_packwiz( + &output_dir, + &http_client, + &server, + &PackwizExportOptions { cf_usecdn }, + ) + .await?; Ok(()) -} \ No newline at end of file +} diff --git a/src/commands/import/mod.rs b/src/commands/import/mod.rs index f066f85..8ca2726 100644 --- a/src/commands/import/mod.rs +++ b/src/commands/import/mod.rs @@ -1,11 +1,11 @@ use anyhow::Result; use clap::{ArgMatches, Command}; -mod url; +mod customs; mod datapack; mod mrpack; mod packwiz; -mod customs; +mod url; pub fn cli() -> Command { Command::new("import") diff --git a/src/commands/init.rs b/src/commands/init.rs index 14f3a0c..2f67799 100644 --- a/src/commands/init.rs +++ b/src/commands/init.rs @@ -1,16 +1,16 @@ use console::style; use dialoguer::Confirm; use dialoguer::{theme::ColorfulTheme, Input, Select}; -use zip::ZipArchive; use std::ffi::OsStr; use std::fs::File; use std::io::Write; use std::path::Path; use tempfile::Builder; +use zip::ZipArchive; use crate::commands::markdown; use crate::create_http_client; -use crate::util::mrpack::{mrpack_source_to_file, mrpack_read_index, mrpack_import_configs}; +use crate::util::mrpack::{mrpack_import_configs, mrpack_read_index, mrpack_source_to_file}; use crate::util::packwiz::{packwiz_fetch_pack_from_src, packwiz_import_from_source}; use crate::{ downloadable::{sources::vanilla::fetch_latest_mcver, Downloadable}, @@ -24,10 +24,7 @@ pub fn cli() -> Command { .about("Initialize a new mcman server") .arg(arg!(--name [NAME] "The name of the server")) .arg(arg!(--mrpack [SRC] "Import from a modrinth modpack")) - .arg( - arg!(--packwiz [SRC] "Import from a packwiz pack") - .visible_alias("pw") - ) + .arg(arg!(--packwiz [SRC] "Import from a packwiz pack").visible_alias("pw")) } #[allow(clippy::too_many_lines)] @@ -76,10 +73,7 @@ pub async fn run(matches: &ArgMatches) -> Result<()> { Ok(()) } -pub async fn init_normal( - http_client: &reqwest::Client, - name: &str, -) -> Result<()> { +pub async fn init_normal(http_client: &reqwest::Client, name: &str) -> Result<()> { let serv_type = Select::with_theme(&ColorfulTheme::default()) .with_prompt("Type of server?") .default(0) @@ -95,7 +89,7 @@ pub async fn init_normal( let mc_version = if is_proxy { "latest".to_owned() } else { - let latest_ver = fetch_latest_mcver(&http_client) + let latest_ver = fetch_latest_mcver(http_client) .await .context("Fetching latest version")?; @@ -136,11 +130,7 @@ pub async fn init_normal( Ok(()) } -pub async fn init_mrpack( - src: &str, - name: &str, - http_client: &reqwest::Client, -) -> Result<()> { +pub async fn init_mrpack(src: &str, name: &str, http_client: &reqwest::Client) -> Result<()> { println!(" > {}", style("Importing from mrpack...").cyan()); let tmp_dir = Builder::new().prefix("mcman-mrpack-import").tempdir()?; @@ -150,12 +140,7 @@ pub async fn init_mrpack( ..Default::default() }; - let f = mrpack_source_to_file( - src, - http_client, - &tmp_dir, - &server - ).await?; + let f = mrpack_source_to_file(src, http_client, &tmp_dir, &server).await?; let mut archive = ZipArchive::new(f).context("reading mrpack zip archive")?; @@ -164,7 +149,7 @@ pub async fn init_mrpack( server.mc_version = if let Some(v) = pack.dependencies.get("minecraft") { v.clone() } else { - let latest_ver = fetch_latest_mcver(&http_client) + let latest_ver = fetch_latest_mcver(http_client) .await .context("Fetching latest version")?; @@ -201,11 +186,14 @@ pub async fn init_mrpack( }; println!(" > {}", style("Importing mods...").green().bold()); - + pack.import_all(&mut server, http_client).await?; - - println!(" > {}", style("Importing configuration files...").green().bold()); - + + println!( + " > {}", + style("Importing configuration files...").green().bold() + ); + let config_count = mrpack_import_configs(&server, &mut archive)?; println!( @@ -222,11 +210,7 @@ pub async fn init_mrpack( Ok(()) } -pub async fn init_packwiz( - src: &str, - name: &str, - http_client: &reqwest::Client, -) -> Result<()> { +pub async fn init_packwiz(src: &str, name: &str, http_client: &reqwest::Client) -> Result<()> { println!(" > {}", style("Importing from packwiz...").cyan()); let mut server = Server { @@ -241,7 +225,7 @@ pub async fn init_packwiz( } else { // TODO: [acceptable-versions] or something idk - let latest_ver = fetch_latest_mcver(&http_client) + let latest_ver = fetch_latest_mcver(http_client) .await .context("Fetching latest version")?; @@ -277,7 +261,8 @@ pub async fn init_packwiz( } }; - let (_pack, mod_count, config_count) = packwiz_import_from_source(http_client, src, &mut server).await?; + let (_pack, mod_count, config_count) = + packwiz_import_from_source(http_client, src, &mut server).await?; println!( " > {} {} {} {} {}", @@ -293,10 +278,7 @@ pub async fn init_packwiz( Ok(()) } -pub fn init_final( - server: &Server, - is_proxy: bool -) -> Result<()> { +pub fn init_final(server: &Server, is_proxy: bool) -> Result<()> { server.save()?; initialize_environment(is_proxy).context("Initializing environment")?; @@ -311,7 +293,7 @@ pub fn init_final( }; if write_readme { - markdown::initialize_readme(&server).context("Initializing readme")?; + markdown::initialize_readme(server).context("Initializing readme")?; } println!( diff --git a/src/commands/mod.rs b/src/commands/mod.rs index a47d224..8c01beb 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -1,9 +1,9 @@ pub mod build; -pub mod import; +pub mod eject; pub mod export; +pub mod import; pub mod info; pub mod init; pub mod markdown; pub mod pull; pub mod version; -pub mod eject; diff --git a/src/downloadable/import_url.rs b/src/downloadable/import_url.rs index 63d9b84..10ea490 100644 --- a/src/downloadable/import_url.rs +++ b/src/downloadable/import_url.rs @@ -6,8 +6,9 @@ use crate::{downloadable::sources::curserinth::fetch_curserinth_versions, model: use super::{ sources::{ + curserinth::CurseRinthVersion, github::fetch_github_releases, - modrinth::{fetch_modrinth_versions, ModrinthVersion}, curserinth::CurseRinthVersion, + modrinth::{fetch_modrinth_versions, ModrinthVersion}, }, Downloadable, }; @@ -194,10 +195,11 @@ impl Downloadable { ))?; } - let id = "mod__".to_owned() + segments - .get(2) - .ok_or_else(|| anyhow!("Invalid Curseforge URL - mod id not found in URL"))? - .to_owned(); + let id = "mod__".to_owned() + + segments + .get(2) + .ok_or_else(|| anyhow!("Invalid Curseforge URL - mod id not found in URL"))? + .to_owned(); let version = if let Some(v) = segments.get(4) { v.to_owned().to_owned() diff --git a/src/downloadable/markdown.rs b/src/downloadable/markdown.rs index f3b9e73..c60bb3f 100644 --- a/src/downloadable/markdown.rs +++ b/src/downloadable/markdown.rs @@ -314,11 +314,13 @@ impl Downloadable { Self::Spigot { id } => format!("Spigot/{id}"), Self::GithubRelease { repo, .. } => format!("Github/{repo}"), Self::Jenkins { job, .. } => format!("Jenkins/{job}"), - Self::Url { filename, .. } => if let Some(f) = filename { - format!("URL/{f}") - } else { - format!("URL") - }, + Self::Url { filename, .. } => { + if let Some(f) = filename { + format!("URL/{f}") + } else { + "URL".to_string() + } + } _ => self.get_type_name(), } diff --git a/src/downloadable/mod.rs b/src/downloadable/mod.rs index 0043192..4776681 100644 --- a/src/downloadable/mod.rs +++ b/src/downloadable/mod.rs @@ -1,4 +1,4 @@ -use anyhow::{Result, anyhow}; +use anyhow::{anyhow, Result}; use serde::{Deserialize, Serialize}; use crate::{ @@ -10,7 +10,7 @@ use self::sources::{ curserinth::{download_curserinth, fetch_curserinth_filename, get_curserinth_url}, fabric::download_fabric, github::{download_github_release, fetch_github_release_filename, get_github_release_url}, - jenkins::{download_jenkins, get_jenkins_filename, get_jenkins_download_url}, + jenkins::{download_jenkins, get_jenkins_download_url, get_jenkins_filename}, modrinth::{download_modrinth, fetch_modrinth_filename, get_modrinth_url}, papermc::{download_papermc_build, fetch_papermc_build}, purpur::{download_purpurmc_build, fetch_purpurmc_builds}, diff --git a/src/downloadable/sources/curserinth.rs b/src/downloadable/sources/curserinth.rs index 22b2fdd..744326e 100644 --- a/src/downloadable/sources/curserinth.rs +++ b/src/downloadable/sources/curserinth.rs @@ -1,7 +1,7 @@ use anyhow::{bail, Result}; -use serde::{Serialize, Deserialize}; +use serde::{Deserialize, Serialize}; -use super::modrinth::{ModrinthProject, VersionType, ModrinthFile}; +use super::modrinth::{ModrinthFile, ModrinthProject, VersionType}; #[derive(Debug, Deserialize, Serialize, Clone)] #[serde(rename_all = "snake_case")] diff --git a/src/downloadable/sources/spigot.rs b/src/downloadable/sources/spigot.rs index 4cc1b48..1774fa0 100644 --- a/src/downloadable/sources/spigot.rs +++ b/src/downloadable/sources/spigot.rs @@ -51,13 +51,9 @@ pub async fn fetch_spigot_resource_latest_ver( Ok(project.id.to_string()) } -pub fn get_spigot_url( - id: &str, -) -> String { +pub fn get_spigot_url(id: &str) -> String { let id_parsed = get_resource_id(id); - format!( - "https://api.spiget.org/v2/resources/{id_parsed}/download" - ) + format!("https://api.spiget.org/v2/resources/{id_parsed}/download") } pub async fn download_spigot_resource( diff --git a/src/main.rs b/src/main.rs index 7817b71..98eb4f6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ #![allow(clippy::missing_errors_doc)] #![allow(clippy::module_name_repetitions)] #![allow(clippy::struct_excessive_bools)] +#![allow(unknown_lints)] use anyhow::{Context, Result}; use clap::Command; @@ -46,7 +47,7 @@ async fn main() -> Result<()> { Some(("info", _)) => commands::info::run(), Some(("version" | "v", _)) => commands::version::run().await, Some(("export", sub_matches)) => commands::export::run(sub_matches).await, - Some(("eject", _)) => commands::eject::run().await, + Some(("eject", _)) => commands::eject::run(), _ => unreachable!(), } } diff --git a/src/util/mrpack.rs b/src/util/mrpack.rs index 15e31d6..837445f 100644 --- a/src/util/mrpack.rs +++ b/src/util/mrpack.rs @@ -1,26 +1,32 @@ -use anyhow::{Context, Result, anyhow, bail}; +use anyhow::{anyhow, bail, Context, Result}; use console::style; use dialoguer::{theme::ColorfulTheme, Select}; use indexmap::IndexMap; use pathdiff::diff_paths; use reqwest::Url; use serde::{Deserialize, Serialize}; -use tempfile::TempDir; -use walkdir::WalkDir; use std::{ collections::HashMap, fs::{self, File}, io::{Read, Seek, Write}, - path::{PathBuf, Path}, + path::{Path, PathBuf}, }; -use zip::{ZipArchive, write::FileOptions}; +use tempfile::TempDir; +use walkdir::WalkDir; +use zip::{write::FileOptions, ZipArchive}; use crate::{ downloadable::{ - sources::{modrinth::{fetch_modrinth_versions, ModrinthVersion, fetch_modrinth_project, DependencyType}, curserinth::{fetch_curserinth_project, fetch_curserinth_versions}}, + sources::{ + curserinth::{fetch_curserinth_project, fetch_curserinth_versions}, + modrinth::{ + fetch_modrinth_project, fetch_modrinth_versions, DependencyType, ModrinthVersion, + }, + }, Downloadable, }, - model::{Server, ClientSideMod}, util::download_with_progress, + model::{ClientSideMod, Server}, + util::download_with_progress, }; use super::md::MarkdownTable; @@ -102,13 +108,13 @@ pub async fn mrpack_source_to_file( src: &str, http_client: &reqwest::Client, tmp_dir: &TempDir, - server: &Server + server: &Server, ) -> Result { let filename = if src.starts_with("http") || src.starts_with("mr:") { let filename = tmp_dir.path().join("pack.mrpack"); let file = tokio::fs::File::create(&filename).await?; - let downloadable = resolve_mrpack_source(src, &http_client).await?; + let downloadable = resolve_mrpack_source(src, http_client).await?; println!(" > {}", style("Downloading mrpack...").green()); @@ -117,8 +123,8 @@ pub async fn mrpack_source_to_file( &format!("Downloading {src}..."), &downloadable, None, - &server, - &http_client, + server, + http_client, ) .await?; @@ -143,7 +149,7 @@ pub async fn import_from_mrpack( println!(" > {}", style("Reading index...").cyan()); let pack = mrpack_read_index(&mut archive)?; - + pack.import_all(server, http_client) .await .context("importing from mrpack index")?; @@ -164,9 +170,7 @@ pub async fn import_from_mrpack( Ok(pack) } -pub fn mrpack_read_index( - archive: &mut ZipArchive -) -> Result { +pub fn mrpack_read_index(archive: &mut ZipArchive) -> Result { let mut mr_index = archive.by_name("modrinth.index.json")?; let mut zip_content = Vec::new(); mr_index @@ -180,7 +184,7 @@ pub fn mrpack_read_index( pub fn mrpack_import_configs( server: &Server, - archive: &mut ZipArchive + archive: &mut ZipArchive, ) -> Result { let mut server_overrided = vec![]; let mut queue = vec![]; @@ -228,9 +232,13 @@ pub fn mrpack_import_configs( real_path.display() ))?; - fs::write(&real_path, zip_content).context(format!("Writing {}", real_path.display()))?; + fs::write(real_path, zip_content).context(format!("Writing {}", real_path.display()))?; - println!(" > ({:idx_w$}/{len}) Config file: {}", idx + 1, style(path.to_string_lossy()).dim()); + println!( + " > ({:idx_w$}/{len}) Config file: {}", + idx + 1, + style(path.to_string_lossy()).dim() + ); } Ok(len) @@ -313,6 +321,7 @@ pub async fn resolve_mrpack_source( Ok(downloadable) } +#[allow(clippy::too_many_lines)] pub async fn export_mrpack( http_client: &reqwest::Client, server: &Server, @@ -327,19 +336,19 @@ pub async fn export_mrpack( dependencies.insert("minecraft".to_owned(), server.mc_version.clone()); match &server.jar { - Downloadable::Quilt { loader, .. } - => dependencies.insert("quilt-loader".to_owned(), loader.clone()), - Downloadable::Fabric { loader, .. } - => dependencies.insert("fabric-loader".to_owned(), loader.clone()), + Downloadable::Quilt { loader, .. } => { + dependencies.insert("quilt-loader".to_owned(), loader.clone()) + } + Downloadable::Fabric { loader, .. } => { + dependencies.insert("fabric-loader".to_owned(), loader.clone()) + } _ => None, }; - let to_env = |dt: &DependencyType| { - match dt { - DependencyType::Optional => EnvSupport::Optional, - DependencyType::Unsupported | DependencyType::Incompatible => EnvSupport::Unsupported, - _ => EnvSupport::Required - } + let to_env = |dt: &DependencyType| match dt { + DependencyType::Optional => EnvSupport::Optional, + DependencyType::Unsupported | DependencyType::Incompatible => EnvSupport::Unsupported, + _ => EnvSupport::Required, }; let mut files = vec![]; @@ -358,7 +367,10 @@ pub async fn export_mrpack( let verdata = match version.as_str() { "latest" => project.first(), id => project.iter().find(|&v| v.id == id), - }.ok_or(anyhow!(format!("Cant find modrinth version of {id}, ver={version}")))?; + } + .ok_or(anyhow!(format!( + "Cant find modrinth version of {id}, ver={version}" + )))?; // bad unwrap? let file = verdata.files.first().unwrap(); @@ -370,9 +382,7 @@ pub async fn export_mrpack( server: to_env(&proj.server_side), }), path: format!("mods/{}", file.filename), - downloads: vec![ - file.url.clone() - ], + downloads: vec![file.url.clone()], }); println!( @@ -381,7 +391,7 @@ pub async fn export_mrpack( style("Converted").green(), serv_mod.to_short_string() ); - }, + } Downloadable::CurseRinth { id, version } => { let proj = fetch_curserinth_project(http_client, id).await?; @@ -390,7 +400,10 @@ pub async fn export_mrpack( let verdata = match version.as_str() { "latest" => project.first(), id => project.iter().find(|&v| v.id == id), - }.ok_or(anyhow!(format!("Cant find curserinth version of {id}, ver={version}")))?; + } + .ok_or(anyhow!(format!( + "Cant find curserinth version of {id}, ver={version}" + )))?; // bad unwrap #2? let file = verdata.files.first().unwrap(); @@ -402,9 +415,7 @@ pub async fn export_mrpack( server: to_env(&proj.server_side), }), path: format!("mods/{}", file.filename), - downloads: vec![ - file.url.clone() - ], + downloads: vec![file.url.clone()], }); println!( @@ -413,17 +424,15 @@ pub async fn export_mrpack( style("Converted").green(), serv_mod.to_short_string() ); - }, + } dl => { let filename = dl.get_filename(server, http_client).await?; if let Ok(url) = dl.get_url(http_client, Some(&filename)).await { files.push(MRPackFile { hashes: HashMap::new(), // ! todo...??? env: None, - path: format!("mods/{}", filename), - downloads: vec![ - url - ], + path: format!("mods/{filename}"), + downloads: vec![url], }); println!( @@ -444,7 +453,10 @@ pub async fn export_mrpack( } } - println!(" > {}", style("Converting client-side mods...").cyan().bold()); + println!( + " > {}", + style("Converting client-side mods...").cyan().bold() + ); let len = server.clientsidemods.len(); let idx_w = len.to_string().len(); @@ -458,7 +470,10 @@ pub async fn export_mrpack( let verdata = match version.as_str() { "latest" => project.first(), id => project.iter().find(|&v| v.id == id), - }.ok_or(anyhow!(format!("Cant find modrinth version of {id}, ver={version}")))?; + } + .ok_or(anyhow!(format!( + "Cant find modrinth version of {id}, ver={version}" + )))?; // bad unwrap? let file = verdata.files.first().unwrap(); @@ -474,9 +489,7 @@ pub async fn export_mrpack( server: to_env(&proj.server_side), }), path: format!("mods/{}", file.filename), - downloads: vec![ - file.url.clone() - ], + downloads: vec![file.url.clone()], }); println!( @@ -485,7 +498,7 @@ pub async fn export_mrpack( style("Converted").green(), client_mod.dl.to_short_string() ); - }, + } Downloadable::CurseRinth { id, version } => { let proj = fetch_curserinth_project(http_client, id).await?; @@ -494,7 +507,10 @@ pub async fn export_mrpack( let verdata = match version.as_str() { "latest" => project.first(), id => project.iter().find(|&v| v.id == id), - }.ok_or(anyhow!(format!("Cant find curserinth version of {id}, ver={version}")))?; + } + .ok_or(anyhow!(format!( + "Cant find curserinth version of {id}, ver={version}" + )))?; // bad unwrap #2? let file = verdata.files.first().unwrap(); @@ -510,9 +526,7 @@ pub async fn export_mrpack( server: to_env(&proj.server_side), }), path: format!("mods/{}", file.filename), - downloads: vec![ - file.url.clone() - ], + downloads: vec![file.url.clone()], }); println!( @@ -521,17 +535,15 @@ pub async fn export_mrpack( style("Converted").green(), client_mod.dl.to_short_string() ); - }, + } dl => { let filename = dl.get_filename(server, http_client).await?; if let Ok(url) = dl.get_url(http_client, Some(&filename)).await { files.push(MRPackFile { hashes: HashMap::new(), // ! todo...??? env: None, - path: format!("mods/{}", filename), - downloads: vec![ - url - ], + path: format!("mods/{filename}"), + downloads: vec![url], }); println!( @@ -566,15 +578,15 @@ pub async fn export_mrpack( dependencies, game: "minecraft".to_owned(), files, - version_id: version_id.to_owned() + version_id: version_id.to_owned(), }; println!(" > {}", style("Writing index...").cyan().bold()); - + archive.start_file("modrinth.index.json", FileOptions::default())?; - + archive.write_all(serde_json::to_string_pretty(&index)?.as_bytes())?; - + if server.path.join("config").exists() { println!(" > {}", style("Writing config/...").cyan().bold()); @@ -588,24 +600,27 @@ pub async fn export_mrpack( ); } }; - - let rel_path = diff_paths(entry.path(), &server.path.join("config")).ok_or(anyhow!("Cannot diff paths"))?; - + + let rel_path = diff_paths(entry.path(), &server.path.join("config")) + .ok_or(anyhow!("Cannot diff paths"))?; + let dest_path = "overrides/".to_owned() + &rel_path.to_string_lossy(); - + if entry.file_type().is_dir() { - archive.add_directory(dest_path.clone(), FileOptions::default()) + archive + .add_directory(dest_path.clone(), FileOptions::default()) .context(format!("Creating dir in zip: {dest_path}"))?; } else { - archive.start_file(dest_path.clone(), FileOptions::default()) + archive + .start_file(dest_path.clone(), FileOptions::default()) .context(format!("Starting zip file for {dest_path}"))?; - - let mut real_file = fs::File::open(entry.path()) - .context(format!("Opening file {dest_path}"))?; - + + let mut real_file = + fs::File::open(entry.path()).context(format!("Opening file {dest_path}"))?; + std::io::copy(&mut real_file, &mut archive) .context(format!("Copying {dest_path} to in-memory zip archive"))?; - + println!(" -> {}", style(dest_path).dim()); } } @@ -624,29 +639,32 @@ pub async fn export_mrpack( ); } }; - - let rel_path = diff_paths(entry.path(), &server.path.join("client-config")).ok_or(anyhow!("Cannot diff paths"))?; - + + let rel_path = diff_paths(entry.path(), &server.path.join("client-config")) + .ok_or(anyhow!("Cannot diff paths"))?; + let dest_path = "client-overrides/".to_owned() + &rel_path.to_string_lossy(); - + if entry.file_type().is_dir() { - archive.add_directory(dest_path.clone(), FileOptions::default()) + archive + .add_directory(dest_path.clone(), FileOptions::default()) .context(format!("Creating dir in zip: {dest_path}"))?; } else { - archive.start_file(dest_path.clone(), FileOptions::default()) + archive + .start_file(dest_path.clone(), FileOptions::default()) .context(format!("Starting zip file for {dest_path}"))?; - - let mut real_file = fs::File::open(entry.path()) - .context(format!("Opening file {dest_path}"))?; - + + let mut real_file = + fs::File::open(entry.path()).context(format!("Opening file {dest_path}"))?; + std::io::copy(&mut real_file, &mut archive) .context(format!("Copying {dest_path} to in-memory zip archive"))?; - + println!(" -> {}", style(dest_path).dim()); } } } - + archive.finish().context("Finishing zip archive")?; println!(" > {}", style("Export complete!").green().bold()); diff --git a/src/util/packwiz.rs b/src/util/packwiz.rs index 054e428..29d9bf1 100644 --- a/src/util/packwiz.rs +++ b/src/util/packwiz.rs @@ -1,16 +1,35 @@ -use std::{path::{PathBuf, Path}, collections::HashMap}; +use std::{ + collections::HashMap, + path::{Path, PathBuf}, +}; -use anyhow::{Result, bail, anyhow, Context}; +use anyhow::{anyhow, bail, Context, Result}; use console::style; use futures::StreamExt; use pathdiff::diff_paths; use reqwest::{IntoUrl, Url}; -use rpackwiz::model::{Pack, Mod, ModDownload, DownloadMode, HashFormat, Side, ModOption, ModUpdate, PackIndex, PackFile, ModrinthModUpdate, CurseforgeModUpdate}; +use rpackwiz::model::{ + CurseforgeModUpdate, DownloadMode, HashFormat, Mod, ModDownload, ModOption, ModUpdate, + ModrinthModUpdate, Pack, PackFile, PackIndex, Side, +}; use sha2::{Digest, Sha256}; -use tokio::{fs::{self, File}, io::AsyncWriteExt}; +use tokio::{ + fs::{self, File}, + io::AsyncWriteExt, +}; use walkdir::WalkDir; -use crate::{model::{Server, ClientSideMod}, downloadable::{Downloadable, sources::{modrinth::{fetch_modrinth_project, DependencyType, fetch_modrinth_versions}, curserinth::{fetch_curserinth_project, fetch_curserinth_versions}}}, util::download_with_progress}; +use crate::{ + downloadable::{ + sources::{ + curserinth::{fetch_curserinth_project, fetch_curserinth_versions}, + modrinth::{fetch_modrinth_project, fetch_modrinth_versions, DependencyType}, + }, + Downloadable, + }, + model::{ClientSideMod, Server}, + util::download_with_progress, +}; pub struct PackwizExportOptions { /// false -> use metadata:curseforge, true -> use edge.forgecdn.net @@ -20,28 +39,25 @@ pub struct PackwizExportOptions { pub async fn packwiz_import_from_source( http_client: &reqwest::Client, src: &str, - server: &mut Server + server: &mut Server, ) -> Result<(Pack, usize, usize)> { Ok(if src.starts_with("http") { let base_url = Url::parse(src).context("Parsing source url")?; - packwiz_import_http(&http_client, base_url, server).await? + packwiz_import_http(http_client, base_url, server).await? } else { let base = PathBuf::from(src); - packwiz_import_local(&http_client, base, server).await? + packwiz_import_local(http_client, base, server).await? }) } // bad code #99999 -pub async fn packwiz_fetch_pack_from_src( - http_client: &reqwest::Client, - src: &str, -) -> Result { +pub async fn packwiz_fetch_pack_from_src(http_client: &reqwest::Client, src: &str) -> Result { Ok(if src.starts_with("http") { let base_url = Url::parse(src).context("Parsing source url")?; - fetch_toml(&http_client, base_url.clone()) + fetch_toml(http_client, base_url.clone()) .await .context("Fetching pack.toml")? } else { @@ -52,10 +68,8 @@ pub async fn packwiz_fetch_pack_from_src( } else { base.join("pack.toml") }; - - read_toml(&base) - .await - .context("Reading pack.toml")? + + read_toml(&base).await.context("Reading pack.toml")? }) } @@ -64,16 +78,17 @@ pub async fn packwiz_import_http( base_url: reqwest::Url, server: &mut Server, ) -> Result<(Pack, usize, usize)> { - let pack: Pack = fetch_toml(&http_client, base_url.clone()) + let pack: Pack = fetch_toml(http_client, base_url.clone()) .await .context("Fetching pack.toml")?; - let index_url = base_url.join(&pack.index.file) + let index_url = base_url + .join(&pack.index.file) .context("Resolving pack index url")?; - + println!(" > {}", style("Fetching index...").dim()); - let pack_index: PackIndex = fetch_toml(&http_client, index_url) + let pack_index: PackIndex = fetch_toml(http_client, index_url) .await .context("Fetching pack index")?; @@ -83,7 +98,8 @@ pub async fn packwiz_import_http( let idx_len = pack_index.files.len(); let idx_w = idx_len.to_string().len(); for (idx, file) in pack_index.files.iter().enumerate() { - let file_url = base_url.join(&file.file) + let file_url = base_url + .join(&file.file) .context("Resolving pack file url")?; if file.metafile { println!( @@ -93,12 +109,11 @@ pub async fn packwiz_import_http( file.file ); - let m: Mod = fetch_toml(&http_client, file_url) - .await.context("Fetching metafile toml")?; + let m: Mod = fetch_toml(http_client, file_url) + .await + .context("Fetching metafile toml")?; - let dl = if let Some(dl) = pw_mod_to_dl(&m, http_client, server).await? { - dl - } else { + let Some(dl) = pw_mod_to_dl(&m, http_client, server).await? else { continue; }; @@ -142,21 +157,26 @@ pub async fn packwiz_import_http( fs::create_dir_all(dest_path.parent().expect("Parent to be Some")) .await - .context(format!("Creating parent dir for {}", dest_path.to_string_lossy()))?; + .context(format!( + "Creating parent dir for {}", + dest_path.to_string_lossy() + ))?; download_with_progress( File::create(&dest_path) - .await.context(format!("Creating file {}", dest_path.to_string_lossy()))?, + .await + .context(format!("Creating file {}", dest_path.to_string_lossy()))?, &file.file, &Downloadable::Url { url: file_url.as_str().to_owned(), filename: None, - desc: None + desc: None, }, None, //unneeded - &server, - &http_client - ).await + server, + http_client, + ) + .await .context(format!("Downloading {} from {file_url}", file.file))?; config_count += 1; @@ -169,18 +189,18 @@ pub async fn packwiz_import_http( pub async fn pw_mod_to_dl( m: &Mod, http_client: &reqwest::Client, - server: &Server + server: &Server, ) -> Result> { Ok(Some(if let Some(upd) = &m.update { if let Some(mr) = &upd.modrinth { Downloadable::Modrinth { id: mr.mod_id.clone(), - version: mr.version.clone() + version: mr.version.clone(), } } else if let Some(cf) = &upd.curseforge { Downloadable::CurseRinth { id: cf.project_id.to_string(), - version: cf.file_id.to_string() + version: cf.file_id.to_string(), } } else { println!("ERROR: UNKNOWN MOD UPDATE"); @@ -188,18 +208,23 @@ pub async fn pw_mod_to_dl( } } else { Downloadable::from_url_interactive( - &http_client, - &server, - &m.download.url.clone().ok_or(anyhow!("download url not present"))?, - false - ).await.context("Resolving Downloadable from URL")? + http_client, + server, + &m.download + .url + .clone() + .ok_or(anyhow!("download url not present"))?, + false, + ) + .await + .context("Resolving Downloadable from URL")? })) } pub async fn packwiz_import_local( http_client: &reqwest::Client, base: PathBuf, - server: &mut Server + server: &mut Server, ) -> Result<(Pack, usize, usize)> { let base = if base.ends_with("pack.toml") { base @@ -207,10 +232,8 @@ pub async fn packwiz_import_local( base.join("pack.toml") }; - let pack: Pack = read_toml(&base) - .await - .context("Reading pack.toml")?; - + let pack: Pack = read_toml(&base).await.context("Reading pack.toml")?; + println!(" > {}", style("Reading index...").dim()); let pack_index: PackIndex = read_toml(&base.join(&pack.index.file)) @@ -236,9 +259,7 @@ pub async fn packwiz_import_local( .await .context(format!("Reading toml from {}", file_path.to_string_lossy()))?; - let dl = if let Some(dl) = pw_mod_to_dl(&m, http_client, server).await? { - dl - } else { + let Some(dl) = pw_mod_to_dl(&m, http_client, server).await? else { continue; }; @@ -282,7 +303,10 @@ pub async fn packwiz_import_local( fs::create_dir_all(dest_path.parent().expect("Parent to be Some")) .await - .context(format!("Creating parent dir for {}", dest_path.to_string_lossy()))?; + .context(format!( + "Creating parent dir for {}", + dest_path.to_string_lossy() + ))?; fs::copy(&file.file, dest_path).await?; @@ -293,13 +317,11 @@ pub async fn packwiz_import_local( Ok((pack, mod_count, config_count)) } -pub async fn fetch_toml( - http_client: &reqwest::Client, - url: U, -) -> Result +pub async fn fetch_toml(http_client: &reqwest::Client, url: U) -> Result where T: serde::de::DeserializeOwned, - U: IntoUrl { + U: IntoUrl, +{ let contents = http_client .get(url) .send() @@ -311,13 +333,12 @@ where Ok(toml::from_str(&contents)?) } -pub async fn read_toml( - path: &PathBuf -) -> Result { +pub async fn read_toml(path: &PathBuf) -> Result { let str = fs::read_to_string(path).await?; Ok(toml::from_str(&str)?) } +#[allow(clippy::too_many_lines)] pub async fn export_packwiz( folder: &PathBuf, http_client: &reqwest::Client, @@ -327,7 +348,7 @@ pub async fn export_packwiz( fs::create_dir_all(folder) .await .context("creating output folder")?; - + let mut pack_index = PackIndex { files: vec![], hash_format: HashFormat::Sha256, @@ -346,13 +367,11 @@ pub async fn export_packwiz( for (idx, (name, metafile)) in metafiles.iter().enumerate() { let rel_path = "mods/".to_owned() + name; let path = folder.join(&rel_path); - let contents = toml::to_string_pretty(metafile) - .context("serializing pw mod")?; + let contents = toml::to_string_pretty(metafile).context("serializing pw mod")?; fs::create_dir_all(path.parent().expect("parent of dest present")).await?; - fs::write( - &path, - &contents - ).await.context(format!("Writing {name} metafile"))?; + fs::write(&path, &contents) + .await + .context(format!("Writing {name} metafile"))?; pack_index.files.push(PackFile { file: rel_path.clone(), @@ -384,11 +403,12 @@ pub async fn export_packwiz( ); } }; - - let rel_path = diff_paths(entry.path(), &server.path.join("client-config")).ok_or(anyhow!("Cannot diff paths"))?; - + + let rel_path = diff_paths(entry.path(), &server.path.join("client-config")) + .ok_or(anyhow!("Cannot diff paths"))?; + let dest_path = folder.join(&rel_path); - + if entry.file_type().is_dir() { continue; } @@ -396,15 +416,17 @@ pub async fn export_packwiz( fs::create_dir_all(dest_path.parent().expect("parent of dest present")).await?; // TODO: bootstrapping - fs::copy(entry.path(), &dest_path) - .await - .context(format!("Copying {} to {}", entry.path().to_string_lossy(), dest_path.to_string_lossy()))?; + fs::copy(entry.path(), &dest_path).await.context(format!( + "Copying {} to {}", + entry.path().to_string_lossy(), + dest_path.to_string_lossy() + ))?; pack_index.files.push(PackFile { file: rel_path.to_string_lossy().into_owned(), // maybe problematic? hash: hash_file(&dest_path)?, metafile: true, - + hash_format: None, alias: None, preserve: false, // ? @@ -417,17 +439,16 @@ pub async fn export_packwiz( println!(" > {}", style("Writing pack and index...").cyan()); let mut f = File::create(folder.join("index.toml")).await?; - f.write_all(toml::to_string_pretty(&pack_index)?.as_bytes()).await?; + f.write_all(toml::to_string_pretty(&pack_index)?.as_bytes()) + .await?; let mut versions = HashMap::new(); versions.insert("minecraft".to_owned(), server.mc_version.clone()); match &server.jar { - Downloadable::Quilt { loader, .. } - => versions.insert("quilt".to_owned(), loader.clone()), - Downloadable::Fabric { loader, .. } - => versions.insert("fabric".to_owned(), loader.clone()), + Downloadable::Quilt { loader, .. } => versions.insert("quilt".to_owned(), loader.clone()), + Downloadable::Fabric { loader, .. } => versions.insert("fabric".to_owned(), loader.clone()), _ => None, }; @@ -453,33 +474,47 @@ pub async fn export_packwiz( }; let mut f = File::create(folder.join("pack.toml")).await?; - f.write_all(toml::to_string_pretty(&pack)?.as_bytes()).await?; + f.write_all(toml::to_string_pretty(&pack)?.as_bytes()) + .await?; + + println!( + " > {}", + style("Exported to packwiz successfully!").green().bold() + ); - println!(" > {}", style("Exported to packwiz successfully!").green().bold()); - if let Some(u) = try_get_url(folder) { println!(); println!(" > {}", style("URL (raw.github):").dim()); - println!(" {}", "https://raw.githubusercontent.com/".to_owned() + &u); - println!(" {}", "$INST_JAVA-jar packwiz-installer-bootstrap.jar https://raw.githubusercontent.com/".to_owned() + &u); + println!( + " {}", + "https://raw.githubusercontent.com/".to_owned() + &u + ); + println!( + " {}", + "$INST_JAVA-jar packwiz-installer-bootstrap.jar https://raw.githubusercontent.com/" + .to_owned() + + &u + ); println!(); println!(" > {}", style("URL (githack):").dim()); println!(" {}", "https://raw.githack.com/".to_owned() + &u); - println!(" {}", "$INST_JAVA-jar packwiz-installer-bootstrap.jar https://raw.githack.com/".to_owned() + &u); + println!( + " {}", + "$INST_JAVA-jar packwiz-installer-bootstrap.jar https://raw.githack.com/".to_owned() + + &u + ); println!(); } Ok(()) } -pub fn try_get_url( - folder: &PathBuf -) -> Option { +pub fn try_get_url(folder: &PathBuf) -> Option { let repo_url = get_git_remote()?; let root = get_git_root()?; let branch = get_git_branch()?; - let diff = diff_paths(folder, &root)?; + let diff = diff_paths(folder, root)?; let repo = if repo_url.starts_with("https") { repo_url.strip_prefix("https://github.com/") @@ -487,17 +522,16 @@ pub fn try_get_url( repo_url.strip_prefix("http://github.com/") }?; - Some( - repo.to_owned() + "/" + &branch + "/" + &diff.to_string_lossy() + "/pack.toml" - ) + Some(repo.to_owned() + "/" + &branch + "/" + &diff.to_string_lossy() + "/pack.toml") } pub fn get_git_remote() -> Option { let path = git_command(vec!["remove", "get-url", "origin"])?; - Some(path.strip_suffix(".git") - .map(|o| o.to_owned()) - .unwrap_or(path)) + Some( + path.strip_suffix(".git") + .map_or(path.clone(), ToOwned::to_owned), + ) } pub fn get_git_root() -> Option { @@ -509,10 +543,7 @@ pub fn get_git_branch() -> Option { } pub fn git_command(args: Vec<&str>) -> Option { - let output = std::process::Command::new("git") - .args(args) - .output() - .ok()?; + let output = std::process::Command::new("git").args(args).output().ok()?; if output.status.success() { let path = String::from_utf8_lossy(output.stdout.as_slice()) @@ -533,14 +564,7 @@ pub async fn create_packwiz_modlist( let mut list = vec![]; for dl in &server.mods { - if let Some(t) = dl_to_pw_mod( - dl, - http_client, - server, - opts, - None, - "" - ).await? { + if let Some(t) = dl_to_pw_mod(dl, http_client, server, opts, None, "").await? { list.push(t); } } @@ -552,8 +576,10 @@ pub async fn create_packwiz_modlist( server, opts, Some(client_mod.optional), - &client_mod.desc - ).await? { + &client_mod.desc, + ) + .await? + { list.push(t); } } @@ -561,6 +587,7 @@ pub async fn create_packwiz_modlist( Ok(list) } +#[allow(clippy::too_many_lines)] // xd pub async fn dl_to_pw_mod( dl: &Downloadable, http_client: &reqwest::Client, @@ -586,16 +613,17 @@ pub async fn dl_to_pw_mod( } else { versions.iter().find(|&v| v.id == version.clone()) }; - + let Some(verdata) = verdata else { bail!("Release '{version}' for project '{id}' not found"); }; - + let Some(file) = verdata.files.first() else { bail!("No files for project '{id}' version '{version}'"); }; - let hash = file.hashes + let hash = file + .hashes .get("sha512") .expect("modrinth to provide sha512 hashes") .clone(); @@ -619,15 +647,13 @@ pub async fn dl_to_pw_mod( desc_override.to_owned() }), }, - update: Some( - ModUpdate { - modrinth: Some(ModrinthModUpdate { - mod_id: proj.id, - version: version.to_owned(), - }), - curseforge: None, - } - ), + update: Some(ModUpdate { + modrinth: Some(ModrinthModUpdate { + mod_id: proj.id, + version: version.clone(), + }), + curseforge: None, + }), }; Some((proj.slug + ".pw.toml", m)) @@ -649,16 +675,17 @@ pub async fn dl_to_pw_mod( } else { versions.iter().find(|&v| v.id == version.clone()) }; - + let Some(verdata) = verdata else { bail!("Release '{version}' for project '{id}' not found"); }; - + let Some(file) = verdata.files.first() else { bail!("No files for project '{id}' version '{version}'"); }; - let hash = file.hashes + let hash = file + .hashes .get("sha1") .expect("curserinth to provide sha1 hashes from cf") .clone(); @@ -698,7 +725,7 @@ pub async fn dl_to_pw_mod( modrinth: None, curseforge: Some(CurseforgeModUpdate { file_id: verdata.id.parse()?, - project_id: verdata.project_id.parse()? + project_id: verdata.project_id.parse()?, }), }) }, @@ -710,10 +737,7 @@ pub async fn dl_to_pw_mod( Downloadable::Url { url, desc, .. } => { let filename = dl.get_filename(server, http_client).await?; - let hash = get_hash_url( - http_client, - url, - ).await?; + let hash = get_hash_url(http_client, url).await?; let m = Mod { name: filename.clone(), @@ -721,7 +745,7 @@ pub async fn dl_to_pw_mod( filename: filename.clone(), download: ModDownload { mode: DownloadMode::Url, - url: Some(url.to_owned()), + url: Some(url.clone()), hash, hash_format: HashFormat::Sha256, }, @@ -747,26 +771,21 @@ pub async fn dl_to_pw_mod( }) } -pub fn hash_contents( - contents: &str -) -> String { +pub fn hash_contents(contents: &str) -> String { let mut hasher = Sha256::new(); hasher.update(contents); // unholy hell let hash = (hasher.finalize().as_slice() as &[u8]) - .into_iter() + .iter() .map(|b| format!("{b:x?}")) - .collect::>() - .join(""); + .collect::(); hash } -pub fn hash_file( - path: &PathBuf, -) -> Result { +pub fn hash_file(path: &PathBuf) -> Result { let mut hasher = Sha256::new(); let mut file = std::fs::File::open(path)?; @@ -775,18 +794,14 @@ pub fn hash_file( // unholy hell let hash = (hasher.finalize().as_slice() as &[u8]) - .into_iter() + .iter() .map(|b| format!("{b:x?}")) - .collect::>() - .join(""); + .collect::(); Ok(hash) } -pub async fn get_hash_url( - client: &reqwest::Client, - url: &str -) -> Result { +pub async fn get_hash_url(client: &reqwest::Client, url: &str) -> Result { // rust-analyzer broke let mut hasher = Sha256::new(); @@ -804,10 +819,9 @@ pub async fn get_hash_url( // unholy hell let hash = (hasher.finalize().as_slice() as &[u8]) - .into_iter() + .iter() .map(|b| format!("{b:x?}")) - .collect::>() - .join(""); + .collect::(); Ok(hash) }