You've already forked AstralRinth
forked from didirus/AstralRinth
Project Types, Code Cleanup, and Rename Mods -> Projects (#192)
* Initial work for modpacks and project types * Code cleanup, fix some issues * Username route getting, remove pointless tests * Base validator types + fixes * Fix strange IML generation * Multiple hash requests for version files * Fix docker build (hopefully) * Legacy routes * Finish validator architecture * Update rust version in dockerfile * Added caching and fixed typo (#203) * Added caching and fixed typo * Fixed clippy error * Removed log for cache * Add final validators, fix how loaders are handled and add icons to tags * Fix search module * Fix parts of legacy API not working Co-authored-by: Redblueflame <contact@redblueflame.com>
This commit is contained in:
117
src/validate/mod.rs
Normal file
117
src/validate/mod.rs
Normal file
@@ -0,0 +1,117 @@
|
||||
use crate::models::projects::{GameVersion, Loader};
|
||||
use crate::validate::fabric::FabricValidator;
|
||||
use crate::validate::forge::{ForgeValidator, LegacyForgeValidator};
|
||||
use crate::validate::pack::PackValidator;
|
||||
use chrono::{DateTime, Utc};
|
||||
use std::io::Cursor;
|
||||
use thiserror::Error;
|
||||
use zip::ZipArchive;
|
||||
|
||||
mod fabric;
|
||||
mod forge;
|
||||
mod pack;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum ValidationError {
|
||||
#[error("Unable to read Zip Archive: {0}")]
|
||||
ZipError(#[from] zip::result::ZipError),
|
||||
#[error("IO Error: {0}")]
|
||||
IoError(#[from] std::io::Error),
|
||||
#[error("Error while validating JSON: {0}")]
|
||||
SerDeError(#[from] serde_json::Error),
|
||||
#[error("Invalid Input: {0}")]
|
||||
InvalidInputError(String),
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq)]
|
||||
pub enum ValidationResult {
|
||||
/// File should be marked as primary
|
||||
Pass,
|
||||
/// File should not be marked primary, the reason for which is inside the String
|
||||
Warning(String),
|
||||
}
|
||||
|
||||
pub enum SupportedGameVersions {
|
||||
All,
|
||||
PastDate(DateTime<Utc>),
|
||||
Range(DateTime<Utc>, DateTime<Utc>),
|
||||
Custom(Vec<GameVersion>),
|
||||
}
|
||||
|
||||
pub trait Validator: Sync {
|
||||
fn get_file_extensions<'a>(&self) -> &'a [&'a str];
|
||||
fn get_project_types<'a>(&self) -> &'a [&'a str];
|
||||
fn get_supported_loaders<'a>(&self) -> &'a [&'a str];
|
||||
fn get_supported_game_versions(&self) -> SupportedGameVersions;
|
||||
fn validate(
|
||||
&self,
|
||||
archive: &mut ZipArchive<Cursor<&[u8]>>,
|
||||
) -> Result<ValidationResult, ValidationError>;
|
||||
}
|
||||
|
||||
static VALIDATORS: [&dyn Validator; 4] = [
|
||||
&PackValidator {},
|
||||
&FabricValidator {},
|
||||
&ForgeValidator {},
|
||||
&LegacyForgeValidator {},
|
||||
];
|
||||
|
||||
/// The return value is whether this file should be marked as primary or not, based on the analysis of the file
|
||||
pub fn validate_file(
|
||||
data: &[u8],
|
||||
file_extension: &str,
|
||||
project_type: &str,
|
||||
loaders: Vec<Loader>,
|
||||
game_versions: Vec<GameVersion>,
|
||||
all_game_versions: &[crate::database::models::categories::GameVersion],
|
||||
) -> Result<ValidationResult, ValidationError> {
|
||||
let reader = std::io::Cursor::new(data);
|
||||
let mut zip = zip::ZipArchive::new(reader)?;
|
||||
|
||||
for validator in &VALIDATORS {
|
||||
if validator.get_file_extensions().contains(&file_extension)
|
||||
&& validator.get_project_types().contains(&project_type)
|
||||
&& loaders
|
||||
.iter()
|
||||
.any(|x| validator.get_supported_loaders().contains(&&*x.0))
|
||||
&& game_version_supported(
|
||||
&game_versions,
|
||||
all_game_versions,
|
||||
validator.get_supported_game_versions(),
|
||||
)
|
||||
{
|
||||
return validator.validate(&mut zip);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(ValidationResult::Pass)
|
||||
}
|
||||
|
||||
fn game_version_supported(
|
||||
game_versions: &[GameVersion],
|
||||
all_game_versions: &[crate::database::models::categories::GameVersion],
|
||||
supported_game_versions: SupportedGameVersions,
|
||||
) -> bool {
|
||||
match supported_game_versions {
|
||||
SupportedGameVersions::All => true,
|
||||
SupportedGameVersions::PastDate(date) => game_versions.iter().any(|x| {
|
||||
all_game_versions
|
||||
.iter()
|
||||
.find(|y| y.version == x.0)
|
||||
.map(|x| x.date > date)
|
||||
.unwrap_or(false)
|
||||
}),
|
||||
SupportedGameVersions::Range(before, after) => game_versions.iter().any(|x| {
|
||||
all_game_versions
|
||||
.iter()
|
||||
.find(|y| y.version == x.0)
|
||||
.map(|x| x.date > before && x.date < after)
|
||||
.unwrap_or(false)
|
||||
}),
|
||||
SupportedGameVersions::Custom(versions) => {
|
||||
versions.iter().any(|x| game_versions.contains(x))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//todo: fabric/forge validators for 1.8+ respectively
|
||||
Reference in New Issue
Block a user