From 13309baffa7ea0f4ee3e652425387adfd4f3c573 Mon Sep 17 00:00:00 2001 From: Filip Tibell Date: Sun, 21 Apr 2024 15:09:22 +0200 Subject: [PATCH] Add table builder to utils crate --- Cargo.lock | 3 + crates/lune-utils/Cargo.toml | 3 + crates/lune-utils/src/lib.rs | 4 + crates/lune-utils/src/table_builder.rs | 143 +++++++++++++++++++++++++ 4 files changed, 153 insertions(+) create mode 100644 crates/lune-utils/src/table_builder.rs diff --git a/Cargo.lock b/Cargo.lock index ade73a2..6991ec1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1596,6 +1596,9 @@ version = "0.8.3" [[package]] name = "lune-utils" version = "0.8.3" +dependencies = [ + "mlua", +] [[package]] name = "lz4" diff --git a/crates/lune-utils/Cargo.toml b/crates/lune-utils/Cargo.toml index c38eac7..33dc192 100644 --- a/crates/lune-utils/Cargo.toml +++ b/crates/lune-utils/Cargo.toml @@ -9,3 +9,6 @@ path = "src/lib.rs" [lints] workspace = true + +[dependencies] +mlua = { version = "0.9.7", features = ["async"] } diff --git a/crates/lune-utils/src/lib.rs b/crates/lune-utils/src/lib.rs index 2e802e7..ff27b80 100644 --- a/crates/lune-utils/src/lib.rs +++ b/crates/lune-utils/src/lib.rs @@ -1 +1,5 @@ #![allow(clippy::cargo_common_metadata)] + +mod table_builder; + +pub use self::table_builder::TableBuilder; diff --git a/crates/lune-utils/src/table_builder.rs b/crates/lune-utils/src/table_builder.rs new file mode 100644 index 0000000..1678902 --- /dev/null +++ b/crates/lune-utils/src/table_builder.rs @@ -0,0 +1,143 @@ +#![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) + } +}