refactor: implement 'CompileOptions' & 'LoadOptions' for class luau.* method options

This commit is contained in:
AsynchronousMatrix 2023-08-10 15:21:58 +01:00
parent 34a44be3ff
commit b4ff4a5b06

View file

@ -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<Self> {
Ok(match value {
LuaValue::Nil => Self {
optimization_level: 1,
coverage_level: 0,
debug_level: 1,
},
LuaValue::Table(t) => {
let optimization_level: Option<u8> = t.get("optimizationLevel")?;
let coverage_level: Option<u8> = t.get("coverageLevel")?;
let debug_level: Option<u8> = 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<Self> {
Ok(match value {
LuaValue::Nil => Self {
debug_name: DEFAULT_DEBUG_NAME.to_string(),
},
LuaValue::Table(t) => {
let debug_name: Option<String> = 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<LuaTable> {
TableBuilder::new(lua)?
.with_function("compile", compile_source)?
@ -12,36 +105,13 @@ pub fn create(lua: &'static Lua) -> LuaResult<LuaTable> {
fn compile_source<'lua>(
lua: &'lua Lua,
(source, options): (LuaString<'lua>, Option<LuaTable<'lua>>),
(source, options): (LuaString<'lua>, Option<CompileOptions>),
) -> LuaResult<LuaString<'lua>> {
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<LuaTable<'a>>),
(source, options): (LuaString<'a>, Option<LoadOptions>),
) -> LuaResult<LuaFunction<'a>> {
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()
}