From b4ff4a5b06076b9e552f2c36c7c5710c14e7489c Mon Sep 17 00:00:00 2001 From: AsynchronousMatrix Date: Thu, 10 Aug 2023 15:21:58 +0100 Subject: [PATCH] refactor: implement 'CompileOptions' & 'LoadOptions' for class `luau.*` method options --- src/lune/builtins/luau.rs | 139 +++++++++++++++++++++++++++----------- 1 file changed, 101 insertions(+), 38 deletions(-) diff --git a/src/lune/builtins/luau.rs b/src/lune/builtins/luau.rs index 56aa734..6b84df7 100644 --- a/src/lune/builtins/luau.rs +++ b/src/lune/builtins/luau.rs @@ -3,6 +3,99 @@ use mlua::Compiler as LuaCompiler; use crate::lune::lua::table::TableBuilder; +const DEFAULT_DEBUG_NAME: &str = "luau.load(...)"; + +struct CompileOptions { + pub optimization_level: u8, + pub coverage_level: u8, + pub debug_level: u8, +} + +impl Default for CompileOptions { + fn default() -> Self { + Self { + optimization_level: 1, + coverage_level: 0, + debug_level: 1, + } + } +} + +impl<'lua> FromLua<'lua> for CompileOptions { + fn from_lua(value: LuaValue<'lua>, _: &'lua Lua) -> LuaResult { + Ok(match value { + LuaValue::Nil => Self { + optimization_level: 1, + coverage_level: 0, + debug_level: 1, + }, + LuaValue::Table(t) => { + let optimization_level: Option = t.get("optimizationLevel")?; + let coverage_level: Option = t.get("coverageLevel")?; + let debug_level: Option = t.get("debugLevel")?; + + Self { + optimization_level: optimization_level.unwrap_or(1), + coverage_level: coverage_level.unwrap_or(0), + debug_level: debug_level.unwrap_or(1), + } + } + _ => { + return Err(LuaError::FromLuaConversionError { + from: value.type_name(), + to: "CompileOptions", + message: Some(format!( + "Invalid compile options - expected table, got {}", + value.type_name() + )), + }) + } + }) + } +} + +struct LoadOptions { + pub debug_name: String, +} + +impl Default for LoadOptions { + fn default() -> Self { + Self { + debug_name: DEFAULT_DEBUG_NAME.to_string(), + } + } +} + +impl<'lua> FromLua<'lua> for LoadOptions { + fn from_lua(value: LuaValue<'lua>, _: &'lua Lua) -> LuaResult { + Ok(match value { + LuaValue::Nil => Self { + debug_name: DEFAULT_DEBUG_NAME.to_string(), + }, + LuaValue::Table(t) => { + let debug_name: Option = t.get("debugName")?; + + Self { + debug_name: debug_name.unwrap_or(DEFAULT_DEBUG_NAME.to_string()), + } + } + LuaValue::String(s) => Self { + debug_name: s.to_str()?.to_string(), + }, + _ => { + return Err(LuaError::FromLuaConversionError { + from: value.type_name(), + to: "LoadOptions", + message: Some(format!( + "Invalid compile options - expected string or table, got {}", + value.type_name() + )), + }) + } + }) + } +} + pub fn create(lua: &'static Lua) -> LuaResult { TableBuilder::new(lua)? .with_function("compile", compile_source)? @@ -12,36 +105,13 @@ pub fn create(lua: &'static Lua) -> LuaResult { fn compile_source<'lua>( lua: &'lua Lua, - (source, options): (LuaString<'lua>, Option>), + (source, options): (LuaString<'lua>, Option), ) -> LuaResult> { - let mut optimization_level = 1; - let mut coverage_level = 0; - let mut debug_level = 1; - - if let Some(options) = options { - optimization_level = match options.raw_get("optimizationLevel")? { - LuaValue::Integer(val) => val as u8, - LuaValue::Number(val) => val as u8, - _ => optimization_level, - }; - - coverage_level = match options.raw_get("coverageLevel")? { - LuaValue::Integer(val) => val as u8, - LuaValue::Number(val) => val as u8, - _ => coverage_level, - }; - - debug_level = match options.raw_get("debugLevel")? { - LuaValue::Integer(val) => val as u8, - LuaValue::Number(val) => val as u8, - _ => debug_level, - }; - }; - + let _options = options.unwrap_or_default(); let source_bytecode_bytes = LuaCompiler::default() - .set_optimization_level(optimization_level) - .set_coverage_level(coverage_level) - .set_debug_level(debug_level) + .set_optimization_level(_options.optimization_level) + .set_coverage_level(_options.coverage_level) + .set_debug_level(_options.debug_level) .compile(source); lua.create_string(source_bytecode_bytes) @@ -49,18 +119,11 @@ fn compile_source<'lua>( fn load_source<'a>( lua: &'static Lua, - (source, options): (LuaString<'a>, Option>), + (source, options): (LuaString<'a>, Option), ) -> LuaResult> { - let mut lua_debug_name = None; - - if let Some(options) = options { - lua_debug_name = match options.raw_get("debugName")? { - LuaValue::String(val) => Some(val.to_str()?.to_string()), - _ => lua_debug_name, - }; - } + let _options = options.unwrap_or_default(); lua.load(source.to_str()?.trim_start()) - .set_name(lua_debug_name.unwrap_or("luau.load(...)".to_string())) + .set_name(_options.debug_name) .into_function() }