diff --git a/src/main.rs b/src/main.rs index cc46761..a176714 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1159,7 +1159,7 @@ impl QueryTriple{ 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)->Self{ + fn rojo(search_path:&std::path::PathBuf)->Self{ QueryTriple::rox_rojo(search_path,"init",false) } } @@ -1276,67 +1276,68 @@ fn extract_script_overrides(mut source:String)->AResult{ Ok(ScriptWithOverrides{overrides,source:source.split_off(count)}) } +async fn script_node(search_name:&str,mut file:tokio::fs::File,hint:ScriptHint)->AResult{ + //read entire file + let mut buf=String::new(); + file.read_to_string(&mut buf).await?; + //regex script according to Properties lines at the top + let script_with_overrides=extract_script_overrides(buf)?; + //script + Ok(CompileNode{ + name:script_with_overrides.overrides.name.unwrap_or_else(||search_name.to_owned()), + class:match (script_with_overrides.overrides.class.as_deref(),hint){ + (Some("ModuleScript"),_) + |(None,ScriptHint::ModuleScript|ScriptHint::Undetermined)=>CompileClass::ModuleScript(script_with_overrides.source), + (Some("LocalScript"),_) + |(None,ScriptHint::Script)=>CompileClass::LocalScript(script_with_overrides.source), + (Some("Script"),_) + |(None,ScriptHint::LocalScript)=>CompileClass::Script(script_with_overrides.source), + other=>Err(anyhow::Error::msg(format!("Invalid hint or class {other:?}")))?, + }, + }) +} + +async fn model_node(search_name:&str,mut file:tokio::fs::File)->AResult{ + //read entire file + let mut buf=Vec::new(); + file.read_to_end(&mut buf).await?; + //model + Ok(CompileNode{ + name:search_name.to_owned(), + class:CompileClass::Model(buf), + }) +} + async fn discern_node(entry:&tokio::fs::DirEntry,style:Option)->AResult>{ let contents_folder=entry.path(); let file_name=entry.file_name(); //folder - Ok(if let Ok(dir)=tokio::fs::read_dir(contents_folder.as_path()).await{ + Ok(if tokio::fs::try_exists(contents_folder.as_path()).await?{ let search_name=file_name.to_str().unwrap(); //scan inside the folder for an object to define the class of the folder let script_query=async {match style{ Some(DecompileStyle::Rox)=>QuerySingle::rox(&contents_folder,search_name).resolve().await, Some(DecompileStyle::RoxRojo)=>QueryQuad::rox_rojo(&contents_folder,search_name).resolve().await, - Some(DecompileStyle::Rojo)=>QueryTriple::rojo(&contents_folder,search_name).resolve().await, + Some(DecompileStyle::Rojo)=>QueryTriple::rojo(&contents_folder).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 QueryTriple::rox_rojo(&contents_folder,search_name,true).resolve(), - QueryTriple::rojo(&contents_folder,search_name).resolve(), + QueryTriple::rojo(&contents_folder).resolve(), )) }}; //model files are rox & rox-rojo only, so it's a lot less work... let model_query=get_file_async(contents_folder.clone(),format!("{}.rbxmx",search_name)); //model? script? both? Some(match tokio::join!(script_query,model_query){ - (Ok(FileHint{mut file,hint}),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 - let script_with_overrides=extract_script_overrides(buf)?; - //script - CompileNode{ - name:script_with_overrides.overrides.name.unwrap_or_else(||search_name.to_owned()), - class:match (script_with_overrides.overrides.class.as_deref(),hint){ - (Some("ModuleScript"),_) - |(None,ScriptHint::ModuleScript|ScriptHint::Undetermined)=>CompileClass::ModuleScript(script_with_overrides.source), - (Some("LocalScript"),_) - |(None,ScriptHint::Script)=>CompileClass::LocalScript(script_with_overrides.source), - (Some("Script"),_) - |(None,ScriptHint::LocalScript)=>CompileClass::Script(script_with_overrides.source), - other=>Err(anyhow::Error::msg(format!("Invalid hint or class {other:?}")))?, - }, - 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{ - name:search_name.to_owned(), - class:CompileClass::Model(buf), - folder:Some(dir), - } - }, + (Ok(FileHint{file,hint}),Err(QueryResolveError::NotFound))=>script_node(search_name,file,hint).await?, + (Err(QueryResolveError::NotFound),Ok(file))=>model_node(search_name,file).await?, (Ok(_),Ok(_))=>Err(QueryResolveError::Ambiguous)?, //neither (Err(QueryResolveError::NotFound),Err(QueryResolveError::NotFound))=>CompileNode{ name:search_name.to_owned(), class:CompileClass::Folder, - folder:Some(dir), }, //other error (Err(e),_) @@ -1348,9 +1349,38 @@ async fn discern_node(entry:&tokio::fs::DirEntry,style:Option)-> }) } + +enum FileDiscernment{ + Model, + Script(ScriptHint), +} + async fn discern_file(entry:&tokio::fs::DirEntry,style:Option)->AResult>{ - todo!(); - Ok(None) + let path=entry.path(); + let file_discernment=match path.extension(){ + Some(extension)=>match extension.to_str(){ + Some(".lua")=>FileDiscernment::Script(ScriptHint::Undetermined), + Some(".module.lua")=>FileDiscernment::Script(ScriptHint::ModuleScript), + Some(".client.lua")=>FileDiscernment::Script(ScriptHint::LocalScript), + Some(".server.lua")=>FileDiscernment::Script(ScriptHint::Script), + Some(".rbxlx")=>FileDiscernment::Model, + other=>Err(anyhow::Error::msg(format!("Weird file extension: {other:?}")))?, + }, + None=>Err(anyhow::Error::msg("No file extension"))?, + }; + //reject goobers + match (style,&file_discernment){ + (Some(DecompileStyle::Rojo),FileDiscernment::Script(ScriptHint::ModuleScript)) + |(Some(DecompileStyle::Rojo),FileDiscernment::Model)=>Err(anyhow::Error::msg("Invalid file extension for style"))?, + _=>(), + } + let search_name=path.to_str().unwrap(); + let file=tokio::fs::File::open(path.as_path()).await?; + Ok(Some(match file_discernment{ + FileDiscernment::Model=>model_node(search_name,file).await?, + FileDiscernment::Script(hint)=>script_node(search_name,file,hint).await?, + })) + } #[derive(Debug)] @@ -1381,7 +1411,6 @@ enum CompileClass{ struct CompileNode{ name:String, class:CompileClass, - folder:Option, } enum CompileStackInstruction{ @@ -1491,7 +1520,7 @@ async fn compile(config:CompileConfig)->AResult<()>{ } let mut output_place=config.output_file.clone(); - if output_place.extension().is_none(){ + if output_place.extension().is_none()&&tokio::fs::try_exists(output_place.as_path()).await?{ output_place.push("place.rbxl"); } let output=std::io::BufWriter::new(std::fs::File::open(output_place)?);