diff --git a/.dockerignore b/.dockerignore index 5727fee..9410af1 100644 --- a/.dockerignore +++ b/.dockerignore @@ -3,4 +3,4 @@ target .gitignore docker-compose.yml Dockerfile -.dockerignore \ No newline at end of file +.dockerignore diff --git a/.gitignore b/.gitignore index ea8c4bf..e1e9c39 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,361 @@ -/target +# Created by https://www.toptal.com/developers/gitignore/api/git,rust,linux,macos,windows,intellij,intellij+all,intellij+iml,rust-analyzer,visualstudiocode +# Edit at https://www.toptal.com/developers/gitignore?templates=git,rust,linux,macos,windows,intellij,intellij+all,intellij+iml,rust-analyzer,visualstudiocode + +### Git ### +# Created by git for backups. To disable backups in Git: +# $ git config --global mergetool.keepBackup false +*.orig + +# Created by git when using merge tools for conflicts +*.BACKUP.* +*.BASE.* +*.LOCAL.* +*.REMOTE.* +*_BACKUP_*.txt +*_BASE_*.txt +*_LOCAL_*.txt +*_REMOTE_*.txt + +### Intellij ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# AWS User-specific +.idea/**/aws.xml + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# SonarLint plugin +.idea/sonarlint/ + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +### Intellij Patch ### +# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 + +# *.iml +# modules.xml +# .idea/misc.xml +# *.ipr + +# Sonarlint plugin +# https://plugins.jetbrains.com/plugin/7973-sonarlint +.idea/**/sonarlint/ + +# SonarQube Plugin +# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin +.idea/**/sonarIssues.xml + +# Markdown Navigator plugin +# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced +.idea/**/markdown-navigator.xml +.idea/**/markdown-navigator-enh.xml +.idea/**/markdown-navigator/ + +# Cache file creation bug +# See https://youtrack.jetbrains.com/issue/JBR-2257 +.idea/$CACHE_FILE$ + +# CodeStream plugin +# https://plugins.jetbrains.com/plugin/12206-codestream +.idea/codestream.xml + +# Azure Toolkit for IntelliJ plugin +# https://plugins.jetbrains.com/plugin/8053-azure-toolkit-for-intellij +.idea/**/azureSettings.xml + +### Intellij+all ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff + +# AWS User-specific + +# Generated files + +# Sensitive or high-churn files + +# Gradle + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake + +# Mongo Explorer plugin + +# File-based project format + +# IntelliJ + +# mpeltonen/sbt-idea plugin + +# JIRA plugin + +# Cursive Clojure plugin + +# SonarLint plugin + +# Crashlytics plugin (for Android Studio and IntelliJ) + +# Editor-based Rest Client + +# Android studio 3.1+ serialized cache file + +### Intellij+all Patch ### +# Ignore everything but code style settings and run configurations +# that are supposed to be shared within teams. + +.idea/* + +!.idea/codeStyles +!.idea/runConfigurations + +### Intellij+iml ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff + +# AWS User-specific + +# Generated files + +# Sensitive or high-churn files + +# Gradle + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake + +# Mongo Explorer plugin + +# File-based project format + +# IntelliJ + +# mpeltonen/sbt-idea plugin + +# JIRA plugin + +# Cursive Clojure plugin + +# SonarLint plugin + +# Crashlytics plugin (for Android Studio and IntelliJ) + +# Editor-based Rest Client + +# Android studio 3.1+ serialized cache file + +### Intellij+iml Patch ### +# Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023 + +*.iml +modules.xml +.idea/misc.xml +*.ipr + +### Linux ### +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### macOS ### +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### macOS Patch ### +# iCloud generated files +*.icloud + +### Rust ### +# Generated by Cargo +# will have compiled files and executables +debug/ +target/ + +# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries +# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html +Cargo.lock + +# These are backup files generated by rustfmt +**/*.rs.bk + +# MSVC Windows builds of rustc generate these, which store debugging information +*.pdb + +### rust-analyzer ### +# Can be generated by other build systems other than cargo (ex: bazelbuild/rust_rules) +rust-project.json + + +### VisualStudioCode ### +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +!.vscode/*.code-snippets + +# Local History for Visual Studio Code +.history/ + +# Built Visual Studio Code Extensions +*.vsix + +### VisualStudioCode Patch ### +# Ignore all local history of files +.history +.ionide + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +# End of https://www.toptal.com/developers/gitignore/api/git,rust,linux,macos,windows,intellij,intellij+all,intellij+iml,rust-analyzer,visualstudiocode diff --git a/.rustfmt.toml b/.rustfmt.toml new file mode 100644 index 0000000..63ac28e --- /dev/null +++ b/.rustfmt.toml @@ -0,0 +1,14 @@ +max_width = 100 +hard_tabs = true +newline_style = "Unix" +use_small_heuristics = "Default" +reorder_imports = true +imports_granularity = "Module" +reorder_modules = true +remove_nested_parens = true +edition = "2021" +merge_derives = true +use_try_shorthand = false +use_field_init_shorthand = false +force_explicit_abi = true +unstable_features = true diff --git a/Cargo.toml b/Cargo.toml index 065ec83..1f2e713 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,4 +15,39 @@ actix-web = "4" serde = { version = "1.0", features = ["derive"] } reqwest = { version = "0.11", default-features = false, features = ["rustls-tls"] } const_format = "0.2.30" -roxmltree = "0.15.1" \ No newline at end of file +roxmltree = "0.15.1" + +[lints.clippy] +all = { level = "warn", priority = -1 } +pedantic = { level = "warn", priority = -1 } +correctness = { level = "warn", priority = -1 } +perf = { level = "warn", priority = -1 } +style = { level = "warn", priority = -1 } +suspicious = { level = "warn", priority = -1 } +complexity = { level = "warn", priority = -1 } +nursery = { level = "warn", priority = -1 } +unnecessary_cast = "warn" +cast_lossless = "warn" +cast_possible_truncation = "warn" +cast_possible_wrap = "warn" +cast_sign_loss = "warn" +dbg_macro = "warn" +deprecated_cfg_attr = "warn" +separated_literal_suffix = "warn" +missing_errors_doc = "allow" +future_not_send = "allow" +module_name_repetitions = "allow" +struct_field_names = "allow" +cast_precision_loss = "allow" +missing_panics_doc = "allow" + +[lints.rust] +unused_qualifications = "warn" +rust_2018_idioms = { level = "warn", priority = -1 } +trivial_casts = "warn" +trivial_numeric_casts = "warn" +unused_allocation = "warn" +unused_import_braces = "warn" +deprecated = "warn" +deprecated_in_future = "forbid" +unused_must_use = "deny" diff --git a/rust-toolchain.toml b/rust-toolchain.toml index d68f65c..5380cb0 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,2 +1,13 @@ [toolchain] channel = "nightly-2024-09-27" +profile = "minimal" +components = [ + "cargo", + "clippy", + "llvm-tools-preview", + "rustc", + "rust-src", + "rustfmt", + "rust-docs", + "rust-analyzer", +] diff --git a/src/main.rs b/src/main.rs index 46d444e..32d113e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,211 +6,214 @@ mod structs; #[macro_use] mod utils; -use actix_web::{get, web::Data, web::Path, App, HttpResponse, HttpServer, Responder}; +use actix_web::web::{Data, Path}; +use actix_web::{get, App, HttpResponse, HttpServer, Responder}; use const_format::formatcp; -use reqwest::{ - header::HeaderMap, - header::{self, HeaderValue}, - Client, -}; +use parsing::MavenParser; +use reqwest::header::{self, HeaderMap, HeaderValue}; +use reqwest::Client; use roxmltree::Document as XMLDocument; use std::env; -use parsing::MavenParser; const USER_AGENT: &str = formatcp!("PolyfrostAPI/{0}", env!("CARGO_PKG_VERSION")); #[get("/")] async fn index() -> impl Responder { - HttpResponse::Ok().body("Hello there") + HttpResponse::Ok().body("Hello there") } #[get("/oneconfig/{version}-{loader}")] +#[allow(clippy::too_many_lines)] async fn oneconfig(data: Data, path: Path<(String, String)>) -> impl Responder { - // Expand params - let (version, loader) = path.into_inner(); - // Get the type of loader based on version and modloader - let loader_type = match loader.as_str() { - // Handle fabric versions - "fabric" => match version.as_str() { - "1.8.9" | "1.12.2" => "prelaunch", - _ => { - return HttpResponse::UnprocessableEntity().json(structs::ErrorResponse { - error: "INVALID_VERSION".to_string(), - message: format!("Version {version} is invalid for fabric loader!"), - }) - } - }, - // Handle forge versions - "forge" => match version.as_str() { - "1.8.9" | "1.12.2" => "launchwrapper", - _ => { - return HttpResponse::UnprocessableEntity().json(structs::ErrorResponse { - error: "INVALID_VERSION".to_string(), - message: format!("Version {version} is invalid for forge loader!"), - }) - } - }, - // Handle invalid versions - _ => { - return HttpResponse::UnprocessableEntity().json(structs::ErrorResponse { - error: "INVALID_LOADER".to_string(), - message: format!("Loader {loader} is invalid!"), - }) - } - }; - // Fetch maven releases data - let client = &data.http_client; - let maven_releases_text: Result = try { - client - .get(format!( - "{0}/releases/cc/polyfrost/oneconfig-{version}-{loader}/maven-metadata.xml", - data.internal_maven_url - )) - .send() - .await? - .text() - .await? - }; - let maven_releases_text = check_internal_error!(maven_releases_text); - - let maven_releases = XMLDocument::parse(&maven_releases_text); - let maven_releases = check_internal_error!(maven_releases); - - let latest_release = maven_releases.root().get_latest(); - let (latest_release, latest_release_time) = check_internal_error!(latest_release, "Unable to parse latest release from maven"); - - // Fetch maven snapshots data - let maven_snapshots_text: Result = try { - client - .get(format!( - "{0}/snapshots/cc/polyfrost/oneconfig-{version}-{loader}/maven-metadata.xml", - data.internal_maven_url - )) - .send() - .await? - .text() - .await? - }; - let maven_snapshots_text = check_internal_error!(maven_snapshots_text); - - let maven_snapshots = XMLDocument::parse(&maven_snapshots_text); - let maven_snapshots = check_internal_error!(maven_snapshots); - - let latest_snapshot = maven_snapshots.root().get_latest(); - let (latest_snapshot, latest_snapshot_time) = check_internal_error!(latest_snapshot, "Unable to parse latest snapshot from maven"); - - // Fetch loader maven data - let maven_loader_text: Result = try { - client - .get(format!( - "{0}/releases/cc/polyfrost/oneconfig-loader-{loader_type}/maven-metadata.xml", - data.internal_maven_url - )) - .send() - .await? - .text() - .await? - }; - let maven_loader_text = check_internal_error!(maven_loader_text); - - let maven_loader = XMLDocument::parse(&maven_loader_text); - let maven_loader = check_internal_error!(maven_loader); - - let latest_loader = maven_loader.root().get_latest(); - let (latest_loader, _) = check_internal_error!(latest_loader, "Unable to parse latest loader from maven"); - - // Construct the release data - let release_url = format!("{0}/releases/cc/polyfrost/oneconfig-{version}-{loader}/{latest_release}/oneconfig-{version}-{loader}-{latest_release}-full.jar", data.public_maven_url); - let release_sha: Result = try { - client + // Expand params + let (version, loader) = path.into_inner(); + // Get the type of loader based on version and modloader + let loader_type = match loader.as_str() { + // Handle fabric versions + "fabric" => match version.as_str() { + "1.8.9" | "1.12.2" => "prelaunch", + _ => { + return HttpResponse::UnprocessableEntity().json(structs::ErrorResponse { + error: "INVALID_VERSION".to_string(), + message: format!("Version {version} is invalid for fabric loader!"), + }) + } + }, + // Handle forge versions + "forge" => match version.as_str() { + "1.8.9" | "1.12.2" => "launchwrapper", + _ => { + return HttpResponse::UnprocessableEntity().json(structs::ErrorResponse { + error: "INVALID_VERSION".to_string(), + message: format!("Version {version} is invalid for forge loader!"), + }) + } + }, + // Handle invalid versions + _ => { + return HttpResponse::UnprocessableEntity().json(structs::ErrorResponse { + error: "INVALID_LOADER".to_string(), + message: format!("Loader {loader} is invalid!"), + }) + } + }; + // Fetch maven releases data + let client = &data.http_client; + let maven_releases_text: Result = try { + client + .get(format!( + "{0}/releases/cc/polyfrost/oneconfig-{version}-{loader}/maven-metadata.xml", + data.internal_maven_url + )) + .send() + .await? + .text() + .await? + }; + let maven_releases_text = check_internal_error!(maven_releases_text); + + let maven_releases = XMLDocument::parse(&maven_releases_text); + let maven_releases = check_internal_error!(maven_releases); + + let latest_release = maven_releases.root().get_latest(); + let (latest_release, latest_release_time) = + check_internal_error!(latest_release, "Unable to parse latest release from maven"); + + // Fetch maven snapshots data + let maven_snapshots_text: Result = try { + client + .get(format!( + "{0}/snapshots/cc/polyfrost/oneconfig-{version}-{loader}/maven-metadata.xml", + data.internal_maven_url + )) + .send() + .await? + .text() + .await? + }; + let maven_snapshots_text = check_internal_error!(maven_snapshots_text); + + let maven_snapshots = XMLDocument::parse(&maven_snapshots_text); + let maven_snapshots = check_internal_error!(maven_snapshots); + + let latest_snapshot = maven_snapshots.root().get_latest(); + let (latest_snapshot, latest_snapshot_time) = check_internal_error!( + latest_snapshot, + "Unable to parse latest snapshot from maven" + ); + + // Fetch loader maven data + let maven_loader_text: Result = try { + client + .get(format!( + "{0}/releases/cc/polyfrost/oneconfig-loader-{loader_type}/maven-metadata.xml", + data.internal_maven_url + )) + .send() + .await? + .text() + .await? + }; + let maven_loader_text = check_internal_error!(maven_loader_text); + + let maven_loader = XMLDocument::parse(&maven_loader_text); + let maven_loader = check_internal_error!(maven_loader); + + let latest_loader = maven_loader.root().get_latest(); + let (latest_loader, _) = + check_internal_error!(latest_loader, "Unable to parse latest loader from maven"); + + // Construct the release data + let release_url = format!("{0}/releases/cc/polyfrost/oneconfig-{version}-{loader}/{latest_release}/oneconfig-{version}-{loader}-{latest_release}-full.jar", data.public_maven_url); + let release_sha: Result = try { + client .get(format!("{0}/releases/cc/polyfrost/oneconfig-{version}-{loader}/{latest_release}/oneconfig-{version}-{loader}-{latest_release}-full.jar.sha256", data.internal_maven_url)) .send() .await? .text() .await? - }; - let releases_info = structs::MavenDataResponse { - url: release_url, - sha256: check_internal_error!( - release_sha - ) - }; - - // Construct the snapshot data - let snapshot_url = format!("{0}/snapshots/cc/polyfrost/oneconfig-{version}-{loader}/{latest_snapshot}/oneconfig-{version}-{loader}-{latest_snapshot}-full.jar", data.public_maven_url); - let snapshot_sha: Result = try { - client + }; + let releases_info = structs::MavenDataResponse { + url: release_url, + sha256: check_internal_error!(release_sha), + }; + + // Construct the snapshot data + let snapshot_url = format!("{0}/snapshots/cc/polyfrost/oneconfig-{version}-{loader}/{latest_snapshot}/oneconfig-{version}-{loader}-{latest_snapshot}-full.jar", data.public_maven_url); + let snapshot_sha: Result = try { + client .get(format!("{0}/snapshots/cc/polyfrost/oneconfig-{version}-{loader}/{latest_snapshot}/oneconfig-{version}-{loader}-{latest_snapshot}-full.jar.sha256", data.internal_maven_url)) .send() .await? .text() .await? - }; - - let snapshot_info = if latest_release_time >= latest_snapshot_time { - releases_info.clone() - } else { - structs::MavenDataResponse { - url: snapshot_url, - sha256: check_internal_error!(snapshot_sha) - } - }; - - // Construct the loader data - let loader_url = format!("{0}/releases/cc/polyfrost/oneconfig-loader-{loader_type}/{latest_loader}/oneconfig-loader-{loader_type}-{latest_loader}.jar", data.public_maven_url); - let loader_sha: Result = try { - client + }; + + let snapshot_info = if latest_release_time >= latest_snapshot_time { + releases_info.clone() + } else { + structs::MavenDataResponse { + url: snapshot_url, + sha256: check_internal_error!(snapshot_sha), + } + }; + + // Construct the loader data + let loader_url = format!("{0}/releases/cc/polyfrost/oneconfig-loader-{loader_type}/{latest_loader}/oneconfig-loader-{loader_type}-{latest_loader}.jar", data.public_maven_url); + let loader_sha: Result = try { + client .get(format!("{0}/releases/cc/polyfrost/oneconfig-loader-{loader_type}/{latest_loader}/oneconfig-loader-{loader_type}-{latest_loader}.jar.sha256", data.internal_maven_url)) .send() .await? .text() .await? - }; - - let loader_info = structs::MavenDataResponse { - url: loader_url, - sha256: check_internal_error!(loader_sha) - }; - - // Return all the combined maven info - HttpResponse::Ok().json( - structs::OneconfigDataResponse { - release: releases_info, - snapshot: snapshot_info, - loader: loader_info - } - ) + }; + + let loader_info = structs::MavenDataResponse { + url: loader_url, + sha256: check_internal_error!(loader_sha), + }; + + // Return all the combined maven info + HttpResponse::Ok().json(structs::OneconfigDataResponse { + release: releases_info, + snapshot: snapshot_info, + loader: loader_info, + }) } #[actix_web::main] async fn main() -> std::io::Result<()> { - let port = env::var("PORT").unwrap_or("8080".to_string()).parse::().expect("Unable to convert PORT variable to number"); - println!("Starting server on port {port}"); - HttpServer::new(|| { - let mut default_headers = HeaderMap::new(); - default_headers.insert(header::USER_AGENT, HeaderValue::from_static(USER_AGENT)); - - App::new() - .app_data( - // Add app data accessible in routes - Data::new(structs::AppState { - // Set public maven url to PUBLIC_MAVEN_URL env var, with the default being the normal https url - public_maven_url: env::var("PUBLIC_MAVEN_URL") - .unwrap_or("https://repo.polyfrost.cc".to_string()), - // Set internal maven url to INTERNAL MAVEN_URL env var, with the default being localhost - internal_maven_url: env::var("INTERNAL_MAVEN_URL") - .unwrap_or("http://localhost:8080".to_string()), - // Create a global http client to be used - http_client: Client::builder() - .default_headers(default_headers) - .build() - .expect("unable to build http client"), - }), - ) - .service(index) - .service(oneconfig) - }) - .bind(("0.0.0.0", port))? - .run() - .await + let port = env::var("PORT") + .unwrap_or_else(|_| "8080".to_string()) + .parse::() + .expect("Unable to convert PORT variable to number"); + println!("Starting server on port {port}"); + HttpServer::new(|| { + let mut default_headers = HeaderMap::new(); + default_headers.insert(header::USER_AGENT, HeaderValue::from_static(USER_AGENT)); + + App::new() + .app_data( + // Add app data accessible in routes + Data::new(structs::AppState { + // Set public maven url to PUBLIC_MAVEN_URL env var, with the default being the normal https url + public_maven_url: env::var("PUBLIC_MAVEN_URL") + .unwrap_or_else(|_| "https://repo.polyfrost.cc".to_string()), + // Set internal maven url to INTERNAL MAVEN_URL env var, with the default being localhost + internal_maven_url: env::var("INTERNAL_MAVEN_URL") + .unwrap_or_else(|_| "http://localhost:8080".to_string()), + // Create a global http client to be used + http_client: Client::builder() + .default_headers(default_headers) + .build() + .expect("unable to build http client"), + }), + ) + .service(index) + .service(oneconfig) + }) + .bind(("0.0.0.0", port))? + .run() + .await } diff --git a/src/parsing.rs b/src/parsing.rs index 21c27f8..b6a1c61 100644 --- a/src/parsing.rs +++ b/src/parsing.rs @@ -1,27 +1,27 @@ use roxmltree::Node; pub trait MavenParser { - fn get_latest(&self) -> Option<(String, u64)>; - fn get_child(&self, name: &str) -> Option>; + fn get_latest(&self) -> Option<(String, u64)>; + fn get_child(&self, name: &str) -> Option>; } impl MavenParser for Node<'_, '_> { - fn get_child(&self, name: &str) -> Option> { - self.descendants() - .find(|&descendent| descendent.tag_name().name() == name) - } + fn get_child(&self, name: &str) -> Option> { + self.descendants() + .find(|&descendent| descendent.tag_name().name() == name) + } - fn get_latest(&self) -> Option<(String, u64)> { - let metadata = self.get_child("metadata")?; - let versioning = metadata.get_child("versioning")?; - Some(( - versioning.get_child("latest")?.text()?.to_owned(), - versioning - .get_child("lastUpdated")? - .text()? - .to_owned() - .parse::() - .ok()?, - )) - } + fn get_latest(&self) -> Option<(String, u64)> { + let metadata = self.get_child("metadata")?; + let versioning = metadata.get_child("versioning")?; + Some(( + versioning.get_child("latest")?.text()?.to_owned(), + versioning + .get_child("lastUpdated")? + .text()? + .to_owned() + .parse::() + .ok()?, + )) + } } diff --git a/src/structs.rs b/src/structs.rs index ca4bfa3..27221ce 100644 --- a/src/structs.rs +++ b/src/structs.rs @@ -2,26 +2,26 @@ use reqwest::Client; use serde::Serialize; pub struct AppState { - pub public_maven_url: String, - pub internal_maven_url: String, - pub http_client: Client, + pub public_maven_url: String, + pub internal_maven_url: String, + pub http_client: Client, } #[derive(Serialize)] pub struct ErrorResponse { - pub error: String, - pub message: String, + pub error: String, + pub message: String, } #[derive(Serialize, Clone)] pub struct MavenDataResponse { - pub url: String, - pub sha256: String, + pub url: String, + pub sha256: String, } #[derive(Serialize)] pub struct OneconfigDataResponse { - pub release: MavenDataResponse, - pub snapshot: MavenDataResponse, - pub loader: MavenDataResponse, + pub release: MavenDataResponse, + pub snapshot: MavenDataResponse, + pub loader: MavenDataResponse, } diff --git a/src/utils.rs b/src/utils.rs index 9941542..2fc1952 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,24 +1,24 @@ macro_rules! check_internal_error { - ( $e:expr ) => { - match $e { - Ok(x) => x, - Err(e) => { - return actix_web::HttpResponse::InternalServerError().json(structs::ErrorResponse { - error: "INTERNAL_SERVER_ERROR".to_string(), - message: e.to_string(), - }) - } - } - }; - ( $e:expr, $err:expr ) => { - match $e { - Some(x) => x, - None => { - return HttpResponse::InternalServerError().json(structs::ErrorResponse { - error: "INTERNAL_SERVER_ERROR".to_string(), - message: $err.to_string(), - }) - } - } - }; + ( $e:expr ) => { + match $e { + Ok(x) => x, + Err(e) => { + return actix_web::HttpResponse::InternalServerError().json(structs::ErrorResponse { + error: "INTERNAL_SERVER_ERROR".to_string(), + message: e.to_string(), + }) + } + } + }; + ( $e:expr, $err:expr ) => { + match $e { + Some(x) => x, + None => { + return HttpResponse::InternalServerError().json(structs::ErrorResponse { + error: "INTERNAL_SERVER_ERROR".to_string(), + message: $err.to_string(), + }) + } + } + }; }