2024-05-12 12:30:32 +01:00
|
|
|
#![allow(clippy::struct_field_names)]
|
|
|
|
|
2023-08-20 01:18:36 +01:00
|
|
|
use mlua::prelude::*;
|
|
|
|
use mlua::Compiler as LuaCompiler;
|
|
|
|
|
|
|
|
const DEFAULT_DEBUG_NAME: &str = "luau.load(...)";
|
|
|
|
|
2024-05-12 12:30:32 +01:00
|
|
|
/**
|
|
|
|
Options for compiling Lua source code.
|
|
|
|
*/
|
|
|
|
#[derive(Debug, Clone, Copy)]
|
2023-08-20 01:18:36 +01:00
|
|
|
pub struct LuauCompileOptions {
|
|
|
|
pub(crate) optimization_level: u8,
|
|
|
|
pub(crate) coverage_level: u8,
|
|
|
|
pub(crate) debug_level: u8,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl LuauCompileOptions {
|
|
|
|
pub fn into_compiler(self) -> LuaCompiler {
|
|
|
|
LuaCompiler::default()
|
|
|
|
.set_optimization_level(self.optimization_level)
|
|
|
|
.set_coverage_level(self.coverage_level)
|
|
|
|
.set_debug_level(self.debug_level)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for LuauCompileOptions {
|
|
|
|
fn default() -> Self {
|
|
|
|
// NOTE: This is the same as LuaCompiler::default() values, but they are
|
|
|
|
// not accessible from outside of mlua so we need to recreate them here.
|
|
|
|
Self {
|
|
|
|
optimization_level: 1,
|
|
|
|
coverage_level: 0,
|
|
|
|
debug_level: 1,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'lua> FromLua<'lua> for LuauCompileOptions {
|
|
|
|
fn from_lua(value: LuaValue<'lua>, _: &'lua Lua) -> LuaResult<Self> {
|
|
|
|
Ok(match value {
|
|
|
|
LuaValue::Nil => Self::default(),
|
|
|
|
LuaValue::Table(t) => {
|
|
|
|
let mut options = Self::default();
|
|
|
|
|
|
|
|
let get_and_check = |name: &'static str| -> LuaResult<Option<u8>> {
|
|
|
|
match t.get(name)? {
|
2023-08-25 01:09:05 +01:00
|
|
|
Some(n @ (0..=2)) => Ok(Some(n)),
|
2023-08-20 01:18:36 +01:00
|
|
|
Some(n) => Err(LuaError::runtime(format!(
|
|
|
|
"'{name}' must be one of: 0, 1, or 2 - got {n}"
|
|
|
|
))),
|
|
|
|
None => Ok(None),
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
if let Some(optimization_level) = get_and_check("optimizationLevel")? {
|
|
|
|
options.optimization_level = optimization_level;
|
|
|
|
}
|
|
|
|
if let Some(coverage_level) = get_and_check("coverageLevel")? {
|
|
|
|
options.coverage_level = coverage_level;
|
|
|
|
}
|
|
|
|
if let Some(debug_level) = get_and_check("debugLevel")? {
|
|
|
|
options.debug_level = debug_level;
|
|
|
|
}
|
|
|
|
|
|
|
|
options
|
|
|
|
}
|
|
|
|
_ => {
|
|
|
|
return Err(LuaError::FromLuaConversionError {
|
|
|
|
from: value.type_name(),
|
|
|
|
to: "CompileOptions",
|
|
|
|
message: Some(format!(
|
|
|
|
"Invalid compile options - expected table, got {}",
|
|
|
|
value.type_name()
|
|
|
|
)),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-04 03:03:47 +01:00
|
|
|
pub struct LuauLoadOptions<'lua> {
|
2023-08-20 01:18:36 +01:00
|
|
|
pub(crate) debug_name: String,
|
2023-10-04 03:03:47 +01:00
|
|
|
pub(crate) environment: Option<LuaTable<'lua>>,
|
2024-06-05 18:02:48 +01:00
|
|
|
pub(crate) inject_globals: bool,
|
|
|
|
pub(crate) codegen_enabled: bool,
|
2023-08-20 01:18:36 +01:00
|
|
|
}
|
|
|
|
|
2023-10-04 03:03:47 +01:00
|
|
|
impl Default for LuauLoadOptions<'_> {
|
2023-08-20 01:18:36 +01:00
|
|
|
fn default() -> Self {
|
|
|
|
Self {
|
|
|
|
debug_name: DEFAULT_DEBUG_NAME.to_string(),
|
2023-10-04 03:03:47 +01:00
|
|
|
environment: None,
|
2024-06-05 18:02:48 +01:00
|
|
|
inject_globals: true,
|
|
|
|
codegen_enabled: false,
|
2023-08-20 01:18:36 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-04 03:03:47 +01:00
|
|
|
impl<'lua> FromLua<'lua> for LuauLoadOptions<'lua> {
|
2023-08-20 01:18:36 +01:00
|
|
|
fn from_lua(value: LuaValue<'lua>, _: &'lua Lua) -> LuaResult<Self> {
|
|
|
|
Ok(match value {
|
|
|
|
LuaValue::Nil => Self::default(),
|
|
|
|
LuaValue::Table(t) => {
|
|
|
|
let mut options = Self::default();
|
|
|
|
|
|
|
|
if let Some(debug_name) = t.get("debugName")? {
|
|
|
|
options.debug_name = debug_name;
|
|
|
|
}
|
|
|
|
|
2023-10-04 03:03:47 +01:00
|
|
|
if let Some(environment) = t.get("environment")? {
|
|
|
|
options.environment = Some(environment);
|
|
|
|
}
|
|
|
|
|
2024-06-05 18:02:48 +01:00
|
|
|
if let Some(inject_globals) = t.get("injectGlobals")? {
|
|
|
|
options.inject_globals = inject_globals;
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(codegen_enabled) = t.get("codegenEnabled")? {
|
|
|
|
options.codegen_enabled = codegen_enabled;
|
|
|
|
}
|
|
|
|
|
2023-08-20 01:18:36 +01:00
|
|
|
options
|
|
|
|
}
|
|
|
|
LuaValue::String(s) => Self {
|
|
|
|
debug_name: s.to_string_lossy().to_string(),
|
2023-10-04 03:03:47 +01:00
|
|
|
environment: None,
|
2024-06-05 18:02:48 +01:00
|
|
|
inject_globals: true,
|
|
|
|
codegen_enabled: false,
|
2023-08-20 01:18:36 +01:00
|
|
|
},
|
|
|
|
_ => {
|
|
|
|
return Err(LuaError::FromLuaConversionError {
|
|
|
|
from: value.type_name(),
|
|
|
|
to: "LoadOptions",
|
|
|
|
message: Some(format!(
|
|
|
|
"Invalid load options - expected string or table, got {}",
|
|
|
|
value.type_name()
|
|
|
|
)),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|