diff --git a/validation/src/check.rs b/validation/src/check.rs index 66962e7..5ee908b 100644 --- a/validation/src/check.rs +++ b/validation/src/check.rs @@ -40,51 +40,74 @@ impl From<crate::nats_types::CheckSubmissionRequest> for CheckRequest{ } } +#[derive(Default)] +pub enum Check{ + Pass, + #[default] + Fail, +} +impl Check{ + fn pass(&self)->bool{ + match self{ + Check::Pass=>true, + Check::Fail=>false, + } + } +} +impl std::fmt::Display for Check{ + fn fmt(&self,f:&mut std::fmt::Formatter<'_>)->std::fmt::Result{ + match self{ + Check::Pass=>write!(f,"passed"), + Check::Fail=>write!(f,"failed"), + } + } +} + #[derive(Default)] pub struct CheckReport{ // === METADATA CHECKS === // the model must have exactly 1 root part (models uploaded to roblox can have multiple roots) - exactly_one_root:bool, + exactly_one_root:Check, // the root must be of class Model - root_is_model:bool, + root_is_model:Check, // the prefix of the model's name must match the game it was submitted for. bhop_ for bhop, and surf_ for surf - model_name_prefix_is_valid:bool, + model_name_prefix_is_valid:Check, // your model's name must match this regex: ^[a-z0-9_] - model_name_is_snake_case:bool, + model_name_is_snake_case:Check, // map must have a StringValue named Creator and DisplayName. additionally, they must both have a value - has_display_name:bool, - has_creator:bool, + has_display_name:Check, + has_creator:Check, // the display name must be capitalized - display_name_is_title_case:bool, + display_name_is_title_case:Check, // you cannot have any Scripts or ModuleScripts that have the keyword 'getfenv" or 'require' // you cannot have more than 50 duplicate scripts // === MODE CHECKS === // Exactly one MapStart - exactly_one_mapstart:bool, + exactly_one_mapstart:Check, // At least one MapFinish - at_least_one_mapfinish:bool, + at_least_one_mapfinish:Check, // Spawn0 or Spawn1 must exist - spawn1_exists:bool, + spawn1_exists:Check, // No duplicate Spawn# - no_duplicate_spawns:bool, + no_duplicate_spawns:Check, // No duplicate WormholeOut# (duplicate WormholeIn# ok) - no_duplicate_wormhole_out:bool, + no_duplicate_wormhole_out:Check, } impl CheckReport{ pub fn pass(&self)->bool{ - return self.exactly_one_root - &&self.root_is_model - &&self.model_name_prefix_is_valid - &&self.model_name_is_snake_case - &&self.has_display_name - &&self.has_creator - &&self.display_name_is_title_case - &&self.exactly_one_mapstart - &&self.at_least_one_mapfinish - &&self.spawn1_exists - &&self.no_duplicate_spawns - &&self.no_duplicate_wormhole_out + return self.exactly_one_root.pass() + &&self.root_is_model.pass() + &&self.model_name_prefix_is_valid.pass() + &&self.model_name_is_snake_case.pass() + &&self.has_display_name.pass() + &&self.has_creator.pass() + &&self.display_name_is_title_case.pass() + &&self.exactly_one_mapstart.pass() + &&self.at_least_one_mapfinish.pass() + &&self.spawn1_exists.pass() + &&self.no_duplicate_spawns.pass() + &&self.no_duplicate_wormhole_out.pass() } } impl std::fmt::Display for CheckReport{ @@ -192,13 +215,13 @@ pub fn check(dom:&rbx_dom_weak::WeakDom)->CheckReport{ return report; }; - report.exactly_one_root=true; + report.exactly_one_root=Check::Pass; if model_instance.class=="Model"{ - report.root_is_model=true; + report.root_is_model=Check::Pass; } if model_instance.name==model_instance.name.to_snake_case(){ - report.model_name_is_snake_case=true; + report.model_name_is_snake_case=Check::Pass; } // extract model info @@ -207,9 +230,9 @@ pub fn check(dom:&rbx_dom_weak::WeakDom)->CheckReport{ // check DisplayName if let Ok(display_name)=display_name{ if !display_name.is_empty(){ - report.has_display_name=true; + report.has_display_name=Check::Pass; if display_name==display_name.to_title_case(){ - report.display_name_is_title_case=true; + report.display_name_is_title_case=Check::Pass; } } } @@ -217,13 +240,13 @@ pub fn check(dom:&rbx_dom_weak::WeakDom)->CheckReport{ // check Creator if let Ok(creator)=creator{ if !creator.is_empty(){ - report.has_creator=true; + report.has_creator=Check::Pass; } } // check GameID if game_id.is_ok(){ - report.model_name_prefix_is_valid=true; + report.model_name_prefix_is_valid=Check::Pass; } // === MODE CHECKS === @@ -257,24 +280,24 @@ pub fn check(dom:&rbx_dom_weak::WeakDom)->CheckReport{ // MapStart must exist && there must be exactly one of any bonus start zones. if counts.mode_start_counts.get(&ModeID::MAIN)==Some(&1) &&counts.mode_start_counts.iter().all(|(_,&c)|c==1){ - report.exactly_one_mapstart=true; + report.exactly_one_mapstart=Check::Pass; } // iterate over start zones if counts.mode_start_counts.iter().all(|(mode_id,_)| // ensure that at least one end zone exists with the same mode id counts.mode_finish_counts.get(mode_id).is_some_and(|&num|0<num) ){ - report.at_least_one_mapfinish=true; + report.at_least_one_mapfinish=Check::Pass; } // Spawn1 must exist if counts.spawn_counts.get(&SpawnID::FIRST).is_some(){ - report.spawn1_exists=true; + report.spawn1_exists=Check::Pass; } if counts.spawn_counts.iter().all(|(_,&c)|c==1){ - report.no_duplicate_spawns=true; + report.no_duplicate_spawns=Check::Pass; } if counts.wormhole_out_counts.iter().all(|(_,&c)|c==1){ - report.no_duplicate_wormhole_out=true; + report.no_duplicate_wormhole_out=Check::Pass; } report