From 15fd698a21dc4c8979b62d2cb884605f712d489c Mon Sep 17 00:00:00 2001 From: Quaternions Date: Mon, 22 Jan 2024 21:36:54 -0800 Subject: [PATCH] colossal fixes & tweaks --- src/main.rs | 94 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 64 insertions(+), 30 deletions(-) diff --git a/src/main.rs b/src/main.rs index 0f1cb81..19dfddf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,7 @@ use clap::{Args,Parser,Subcommand}; use anyhow::Result as AResult; use futures::StreamExt; use rbx_dom_weak::types::Ref; +use tokio::io::AsyncReadExt; type AssetID=u64; type AssetIDFileMap=Vec<(AssetID,std::path::PathBuf)>; @@ -1140,23 +1141,29 @@ impl Query for QuerySingle{ } } struct QueryTriplet{ - shared:QuerySingle, + module:QuerySingle, server:QuerySingle, client:QuerySingle, } impl QueryTriplet{ - fn rox_rojo(search_path:&std::path::PathBuf,search_name:&str)->Self{ + fn rox_rojo(search_path:&std::path::PathBuf,search_name:&str,search_module:bool)->Self{ + //this should be implemented as constructors of Triplet and Quadruplet to fully support Trey's suggestion + let module_name=if search_module{ + format!("{}.module.lua",search_name) + }else{ + format!("{}.lua",search_name) + }; Self{ - shared:QuerySingle(tokio::spawn(get_file_async(search_path.clone(),format!("{}.lua",search_name)))), + module:QuerySingle(tokio::spawn(get_file_async(search_path.clone(),module_name))), server:QuerySingle(tokio::spawn(get_file_async(search_path.clone(),format!("{}.server.lua",search_name)))), client:QuerySingle(tokio::spawn(get_file_async(search_path.clone(),format!("{}.client.lua",search_name)))), } } - fn rojo(search_path:&std::path::PathBuf,search_name:&str,is_subfolder:bool)->Self{ + fn rojo(search_path:&std::path::PathBuf,search_name:&str,search_module:bool,is_subfolder:bool)->Self{ if is_subfolder{ - QueryTriplet::rox_rojo(search_path,"init") + QueryTriplet::rox_rojo(search_path,"init",search_module) }else{ - QueryTriplet::rox_rojo(search_path,search_name) + QueryTriplet::rox_rojo(search_path,search_name,search_module) } } } @@ -1181,42 +1188,69 @@ fn mega_triple_join(query_triplet:(QueryResult,QueryResult,QueryResult))->QueryR } impl Query for QueryTriplet{ async fn resolve(self)->Result{ - let (shared,server,client)=tokio::join!(self.shared.0,self.server.0,self.client.0); + let (module,server,client)=tokio::join!(self.module.0,self.server.0,self.client.0); mega_triple_join(( - shared.map_err(|e|QueryResolveError::JoinError(e))?, + module.map_err(|e|QueryResolveError::JoinError(e))?, server.map_err(|e|QueryResolveError::JoinError(e))?, client.map_err(|e|QueryResolveError::JoinError(e))?, )) } } -async fn find_file(search_path:&std::path::PathBuf,search_name:&str,style:Option)->AResult{ - //figure out something clever for this - let mut what=CompileNode{ - class:CompileClass::Folder, - folder:None, - }; +async fn discern_node(search_path:&std::path::PathBuf,search_name:&str,style:Option)->AResult{ let mut contents_folder=search_path.clone(); contents_folder.push(search_name); //folder if let Ok(dir)=tokio::fs::read_dir(contents_folder.as_path()).await{ - what.folder=Some(dir); + //scan inside the folder for an object to define the class of the folder + let (script_file,model_file)=tokio::join!( + async {match style{ + Some(DecompileStyle::Rox)=>QuerySingle::rox(&contents_folder,search_name).resolve().await, + Some(DecompileStyle::RoxRojo)=>QueryTriplet::rox_rojo(&contents_folder,search_name,false).resolve().await, + Some(DecompileStyle::Rojo)=>QueryTriplet::rojo(&contents_folder,search_name,false,true).resolve().await, + //try all three and complain if there is ambiguity + None=>mega_triple_join(tokio::join!( + QuerySingle::rox(&contents_folder,search_name).resolve(), + //true=search for module here to avoid ambiguity with QuerySingle::rox results + QueryTriplet::rox_rojo(&contents_folder,search_name,true).resolve(), + QueryTriplet::rojo(&contents_folder,search_name,true,true).resolve(), + )) + }}, + //model files are rox & rox-rojo only, so it's a lot less work... + get_file_async(contents_folder.clone(),format!("{}.rbxmx",search_name)) + ); + //model? script? both? + Ok(match (script_file,model_file){ + (Ok(mut file),Err(QueryResolveError::NotFound))=>{ + //read entire file + let mut buf=String::new(); + file.read_to_string(&mut buf).await?; + //regex script according to Properties lines at the top + todo!("unimplemented"); + //script + CompileNode{ + class:CompileClass::Script(buf), + folder:Some(dir), + } + }, + (Err(QueryResolveError::NotFound),Ok(mut file))=>{ + //read entire file + let mut buf=Vec::new(); + file.read_to_end(&mut buf).await?; + //model + CompileNode{ + class:CompileClass::Model(buf), + folder:Some(dir), + } + }, + (Ok(_),Ok(_))=>Err(QueryResolveError::Ambiguous)?, + //other error + (Err(e),_) + |(_,Err(e))=>Err(e)? + }) }else{ - contents_folder.pop(); + Err(anyhow::Error::msg("message")) } - let (script_file,model_file)=tokio::join!(async {match style{ - Some(DecompileStyle::Rox)=>QuerySingle::rox(search_path,search_name).resolve().await, - Some(DecompileStyle::RoxRojo)=>QueryTriplet::rox_rojo(search_path,search_name).resolve().await, - Some(DecompileStyle::Rojo)=>QueryTriplet::rojo(search_path,search_name,what.folder.is_some()).resolve().await, - //try all three and complain if there is ambiguity - None=>mega_triple_join(tokio::join!( - QuerySingle::rox(search_path,search_name).resolve(), - QueryTriplet::rox_rojo(search_path,search_name).resolve(), - QueryTriplet::rojo(search_path,search_name,what.folder.is_some()).resolve(), - )) - }},get_file_async(search_path.clone(),format!("{}.rbxmx",search_name))); - - Ok(CompileClass::Folder) } enum CompileClass{ @@ -1267,7 +1301,7 @@ async fn compile(config:CompileConfig)->AResult<()>{ CompileStackInstruction::Referent(item_ref)=>{ let item=dom.get_by_ref(item_ref).ok_or(anyhow::Error::msg("null child ref"))?; //check if item exists in folder or subfolder of same name - if let Ok(obj)=find_file(&folder,item.name.as_str(),None).await{ + if let Ok(obj)=discern_node(&folder,item.name.as_str(),None).await{ //cool }else{ //determine if this is ok