lune_utils/
table_builder.rs

1#![allow(clippy::missing_errors_doc)]
2
3use std::future::Future;
4
5use mlua::prelude::*;
6
7/**
8    Utility struct for building Lua tables.
9*/
10pub struct TableBuilder {
11    lua: Lua,
12    tab: LuaTable,
13}
14
15impl TableBuilder {
16    /**
17        Creates a new table builder.
18    */
19    pub fn new(lua: Lua) -> LuaResult<Self> {
20        let tab = lua.create_table()?;
21        Ok(Self { lua, tab })
22    }
23
24    /**
25        Adds a new key-value pair to the table.
26
27        This will overwrite any value that already exists.
28    */
29    pub fn with_value<K, V>(self, key: K, value: V) -> LuaResult<Self>
30    where
31        K: IntoLua,
32        V: IntoLua,
33    {
34        self.tab.raw_set(key, value)?;
35        Ok(self)
36    }
37
38    /**
39        Adds multiple key-value pairs to the table.
40
41        This will overwrite any values that already exist.
42    */
43    pub fn with_values<K, V>(self, values: Vec<(K, V)>) -> LuaResult<Self>
44    where
45        K: IntoLua,
46        V: IntoLua,
47    {
48        for (key, value) in values {
49            self.tab.raw_set(key, value)?;
50        }
51        Ok(self)
52    }
53
54    /**
55        Adds a new key-value pair to the sequential (array) section of the table.
56
57        This will not overwrite any value that already exists,
58        instead adding the value to the end of the array.
59    */
60    pub fn with_sequential_value<V>(self, value: V) -> LuaResult<Self>
61    where
62        V: IntoLua,
63    {
64        self.tab.raw_push(value)?;
65        Ok(self)
66    }
67
68    /**
69        Adds multiple values to the sequential (array) section of the table.
70
71        This will not overwrite any values that already exist,
72        instead adding the values to the end of the array.
73    */
74    pub fn with_sequential_values<V>(self, values: Vec<V>) -> LuaResult<Self>
75    where
76        V: IntoLua,
77    {
78        for value in values {
79            self.tab.raw_push(value)?;
80        }
81        Ok(self)
82    }
83
84    /**
85        Adds a new key-value pair to the table, with a function value.
86
87        This will overwrite any value that already exists.
88    */
89    pub fn with_function<K, A, R, F>(self, key: K, func: F) -> LuaResult<Self>
90    where
91        K: IntoLua,
92        A: FromLuaMulti,
93        R: IntoLuaMulti,
94        F: Fn(&Lua, A) -> LuaResult<R> + 'static,
95    {
96        let f = self.lua.create_function(func)?;
97        self.with_value(key, LuaValue::Function(f))
98    }
99
100    /**
101        Adds a new key-value pair to the table, with an async function value.
102
103        This will overwrite any value that already exists.
104    */
105    pub fn with_async_function<K, A, R, F, FR>(self, key: K, func: F) -> LuaResult<Self>
106    where
107        K: IntoLua,
108        A: FromLuaMulti,
109        R: IntoLuaMulti,
110        F: Fn(Lua, A) -> FR + 'static,
111        FR: Future<Output = LuaResult<R>> + 'static,
112    {
113        let f = self.lua.create_async_function(func)?;
114        self.with_value(key, LuaValue::Function(f))
115    }
116
117    /**
118        Adds a metatable to the table.
119
120        This will overwrite any metatable that already exists.
121    */
122    pub fn with_metatable(self, table: LuaTable) -> LuaResult<Self> {
123        self.tab.set_metatable(Some(table))?;
124        Ok(self)
125    }
126
127    /**
128        Builds the table as a read-only table.
129
130        This will prevent any *direct* modifications to the table.
131    */
132    pub fn build_readonly(self) -> LuaResult<LuaTable> {
133        self.tab.set_readonly(true);
134        Ok(self.tab)
135    }
136
137    /**
138        Builds the table.
139    */
140    pub fn build(self) -> LuaResult<LuaTable> {
141        Ok(self.tab)
142    }
143}