use crate::{FromLua, FromLuaMulti, Function, IntoLua, Lua, LuaResult};
#[cfg(feature = "sandbox")]
use luars::SandboxConfig;
pub struct Chunk<'lua> {
lua: &'lua mut Lua,
source: String,
name: Option<String>,
#[cfg(feature = "sandbox")]
sandbox: Option<SandboxConfig>,
}
impl<'lua> Chunk<'lua> {
pub(crate) fn new(lua: &'lua mut Lua, source: &str) -> Self {
Chunk {
lua,
source: source.to_owned(),
name: None,
#[cfg(feature = "sandbox")]
sandbox: None,
}
}
pub fn set_name(mut self, name: impl Into<String>) -> Self {
self.name = Some(name.into());
self
}
#[cfg(feature = "sandbox")]
pub fn with_sandbox(mut self, config: &SandboxConfig) -> Self {
self.sandbox = Some(config.clone());
self
}
fn compile_value(&mut self) -> LuaResult<luars::LuaValue> {
#[cfg(feature = "sandbox")]
if let Some(config) = self.sandbox.as_ref() {
return match self.name.as_deref() {
Some(name) => self
.lua
.load_sandboxed_value_with_name(&self.source, name, config),
None => self.lua.load_sandboxed_value(&self.source, config),
};
}
match self.name.as_deref() {
Some(name) => self.lua.load_value_with_name(&self.source, name),
None => self.lua.load_value(&self.source),
}
}
pub fn into_function(mut self) -> LuaResult<Function> {
let value = self.compile_value()?;
self.lua.value_to_function(value)
}
pub fn exec(mut self) -> LuaResult<()> {
let func = self.compile_value()?;
self.lua.call_function_value(func).map(|_| ())
}
pub async fn exec_async(mut self) -> LuaResult<()> {
let func = self.compile_value()?;
self.lua
.call_function_value_async(func, vec![])
.await
.map(|_| ())
}
pub fn eval<R: FromLua>(mut self) -> LuaResult<R> {
let func = self.compile_value()?;
let value = self
.lua
.call_function_value(func)?
.into_iter()
.next()
.unwrap_or_else(luars::LuaValue::nil);
self.lua.unpack_value(value, "chunk.eval")
}
pub async fn eval_async<R: FromLua>(mut self) -> LuaResult<R> {
let func = self.compile_value()?;
let value = self
.lua
.call_function_value_async(func, vec![])
.await?
.into_iter()
.next()
.unwrap_or_else(luars::LuaValue::nil);
self.lua.unpack_value(value, "chunk.eval_async")
}
pub fn eval_multi<R: FromLuaMulti>(mut self) -> LuaResult<R> {
let func = self.compile_value()?;
let values = self.lua.call_function_value(func)?;
self.lua.unpack_multi_values(values, "chunk.eval_multi")
}
pub async fn eval_multi_async<R: FromLuaMulti>(mut self) -> LuaResult<R> {
let func = self.compile_value()?;
let values = self.lua.call_function_value_async(func, vec![]).await?;
self.lua
.unpack_multi_values(values, "chunk.eval_multi_async")
}
pub fn call<A: IntoLua, R: FromLuaMulti>(self, args: A) -> LuaResult<R> {
self.into_function()?.call(args)
}
pub async fn call_async<A: IntoLua, R: FromLuaMulti>(mut self, args: A) -> LuaResult<R> {
let args = self.lua.pack_multi(args, "chunk.call_async")?;
let func = self.compile_value()?;
let values = self.lua.call_function_value_async(func, args).await?;
self.lua.unpack_multi_values(values, "chunk.call_async")
}
pub fn call1<A: IntoLua, R: FromLua>(self, args: A) -> LuaResult<R> {
self.into_function()?.call1(args)
}
pub async fn call1_async<A: IntoLua, R: FromLua>(mut self, args: A) -> LuaResult<R> {
let args = self.lua.pack_multi(args, "chunk.call1_async")?;
let func = self.compile_value()?;
let value = self
.lua
.call_function_value_async(func, args)
.await?
.into_iter()
.next()
.unwrap_or_else(luars::LuaValue::nil);
self.lua.unpack_value(value, "chunk.call1_async")
}
}