#![allow(clippy::missing_errors_doc)] use std::future::Future; use mlua::prelude::*; /** Utility struct for building Lua tables. */ pub struct TableBuilder<'lua> { lua: &'lua Lua, tab: LuaTable<'lua>, } impl<'lua> TableBuilder<'lua> { /** Creates a new table builder. */ pub fn new(lua: &'lua Lua) -> LuaResult { let tab = lua.create_table()?; Ok(Self { lua, tab }) } /** Adds a new key-value pair to the table. This will overwrite any value that already exists. */ pub fn with_value(self, key: K, value: V) -> LuaResult where K: IntoLua<'lua>, V: IntoLua<'lua>, { self.tab.raw_set(key, value)?; Ok(self) } /** Adds multiple key-value pairs to the table. This will overwrite any values that already exist. */ pub fn with_values(self, values: Vec<(K, V)>) -> LuaResult where K: IntoLua<'lua>, V: IntoLua<'lua>, { for (key, value) in values { self.tab.raw_set(key, value)?; } Ok(self) } /** Adds a new key-value pair to the sequential (array) section of the table. This will not overwrite any value that already exists, instead adding the value to the end of the array. */ pub fn with_sequential_value(self, value: V) -> LuaResult where V: IntoLua<'lua>, { self.tab.raw_push(value)?; Ok(self) } /** Adds multiple values to the sequential (array) section of the table. This will not overwrite any values that already exist, instead adding the values to the end of the array. */ pub fn with_sequential_values(self, values: Vec) -> LuaResult where V: IntoLua<'lua>, { for value in values { self.tab.raw_push(value)?; } Ok(self) } /** Adds a new key-value pair to the table, with a function value. This will overwrite any value that already exists. */ pub fn with_function(self, key: K, func: F) -> LuaResult where K: IntoLua<'lua>, A: FromLuaMulti<'lua>, R: IntoLuaMulti<'lua>, F: Fn(&'lua Lua, A) -> LuaResult + 'static, { let f = self.lua.create_function(func)?; self.with_value(key, LuaValue::Function(f)) } /** Adds a new key-value pair to the table, with an async function value. This will overwrite any value that already exists. */ pub fn with_async_function(self, key: K, func: F) -> LuaResult where K: IntoLua<'lua>, A: FromLuaMulti<'lua>, R: IntoLuaMulti<'lua>, F: Fn(&'lua Lua, A) -> FR + 'static, FR: Future> + 'lua, { let f = self.lua.create_async_function(func)?; self.with_value(key, LuaValue::Function(f)) } /** Adds a metatable to the table. This will overwrite any metatable that already exists. */ pub fn with_metatable(self, table: LuaTable) -> LuaResult { self.tab.set_metatable(Some(table)); Ok(self) } /** Builds the table as a read-only table. This will prevent any *direct* modifications to the table. */ pub fn build_readonly(self) -> LuaResult> { self.tab.set_readonly(true); Ok(self.tab) } /** Builds the table. */ pub fn build(self) -> LuaResult> { Ok(self.tab) } }