1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
//! Safe, idiomatic embedding APIs for the Luau runtime.
//!
//! Compiler, syntax, bytecode, code generation, and VM internals remain in
//! their owning crates. This crate exposes the safe lifetime-bound embedding
//! surface.
//!
//! ```
//! # fn main() -> luau::Result<()> {
//! let lua = luau::Lua::new()?;
//! let answer: i32 = lua.load("return 40 + 2").call(())?;
//! assert_eq!(answer, 42);
//! # Ok(())
//! # }
//! ```
//!
//! Use [`callback!`] or [`function!`] to expose typed Rust callbacks. Luau
//! strings, tables, functions, threads, and userdata borrow their [`Lua`]
//! state and cannot outlive it.
extern crate self as luau;
/// Derives [`FromLua`] by borrowing matching typed [`AnyUserdata`] and cloning
/// its Rust payload.
///
/// This does not perform structural conversion from tables or other Luau
/// values. The derived type must implement [`Clone`] and be `'static`.
pub use FromLua;
/// Derives [`Userdata`] and exposes named struct fields to Luau.
///
/// Fields are readable and writable by default. Use `#[luau(...)]` to change
/// their Luau-facing behavior:
///
/// | Attribute | Effect |
/// | --- | --- |
/// | `get` | Expose only the field getter. |
/// | `set` | Expose only the field setter. |
/// | `skip` | Do not expose the field. |
/// | `name = "..."` | Use a different Luau name. |
///
/// Readable fields must implement [`Clone`].
///
/// Apply [`userdata_impl`] to inherent impl blocks to register their associated
/// constants and functions. Multiple attributed impl blocks for the same type
/// compose, including impl blocks in different modules.
/// Every associated constant and function is registered unless it has
/// `#[luau(skip)]`.
///
/// ```
/// # use luau::{AnyUserdata, Lua, Result};
/// #[derive(luau::Userdata)]
/// struct Counter {
/// value: i32,
/// }
///
/// #[luau::userdata_impl]
/// impl Counter {
/// #[luau(infallible)]
/// fn new(value: i32) -> Self {
/// Self { value }
/// }
///
/// #[luau(infallible)]
/// fn increment(&mut self, amount: Option<i32>) -> i32 {
/// self.value += amount.unwrap_or(1);
/// self.value
/// }
///
/// #[luau(meta, infallible)]
/// fn __call(_proxy: AnyUserdata<'_>, value: i32) -> Self {
/// Self { value }
/// }
/// }
///
/// # fn main() -> Result<()> {
/// let lua = Lua::new()?;
/// lua.globals()?.set("Counter", lua.create_proxy::<Counter>()?)?;
/// let value: i32 = lua.load("return Counter(40):increment(2)").call(())?;
/// assert_eq!(value, 42);
/// # Ok(())
/// # }
/// ```
///
/// The receiver selects the registration kind:
///
/// | Receiver | Registration |
/// | --- | --- |
/// | `&self` | Immutable method |
/// | `&mut self` | Mutable method |
/// | `self` | Consuming method |
/// | None | Type function |
///
/// A first typed parameter of [`LuaRef`] is supplied by the callback and is not
/// read from Luau arguments. Other parameters are converted normally, with
/// these borrowed forms handled directly:
///
/// | Parameter | Value borrowed for the call |
/// | --- | --- |
/// | `&str` | Luau string text |
/// | `&[u8]` | Luau string bytes |
/// | `&T` | Typed userdata |
/// | `&mut T` | Mutably borrowed typed userdata |
///
/// These forms may also be wrapped in [`Option`]. The final non-reference
/// parameter is converted through [`FromLuaMulti`] and can consume the
/// remaining arguments.
///
/// Items in a [`userdata_impl`] block support:
///
/// | Attribute | Applies to | Effect |
/// | --- | --- | --- |
/// | `skip` | Functions, constants | Do not register the item. |
/// | `name = "..."` | Functions, constants | Use a different Luau name. |
/// | `infallible` | Functions | Treat the Rust return value as successful. |
/// | `get` | Functions | Register an `&self` function as a field getter. |
/// | `set` | Functions | Register an `&self` or `&mut self` function as a field setter. |
/// | `field` | Functions | Register a receiver-free function as a type field. |
/// | `meta` | Functions, constants | Register a metamethod or meta field. |
///
/// A `field` function is evaluated once when the userdata type is registered.
/// It takes no Luau arguments, but may receive [`LuaRef`] and return a
/// lifetime-bound value. Combine `field` with `meta` to register a computed
/// metatable field.
///
/// Associated constants are type fields by default. A receiver-free
/// metamethod receives every argument Luau passes; for `__call` on a type
/// proxy, this includes the proxy itself.
///
/// Generic userdata derives and generic impl blocks are not supported.
/// Unions are not supported. Tuple structs, unit structs, and enums derive the
/// trait without fields and can define their surface through
/// [`userdata_impl`]. Lifetime parameters on exposed methods are supported.
pub use Userdata;
/// Creates a source chunk that may capture Rust values.
///
/// Prefix a Rust identifier with `$` to place its value in the chunk
/// environment. Captured values are moved into the chunk and converted through
/// [`IntoLua`] when the chunk is passed to [`Lua::load`].
///
/// ```
/// # use luau::{Lua, Result};
/// # fn main() -> Result<()> {
/// let lua = Lua::new()?;
/// let name = String::from("Luau");
/// let greeting: String = lua
/// .load(luau::chunk! {
/// return "hello, " .. $name
/// })
/// .call(())?;
/// assert_eq!(greeting, "hello, Luau");
/// # Ok(())
/// # }
/// ```
///
/// The capture environment preserves `nil`: a captured `None` shadows a
/// global with the same name. Assignments to captured names remain in that
/// environment; other global reads and writes use the current global table.
///
/// `chunk!` uses Rust's tokenizer, so Luau source must also be valid Rust
/// tokens. Notable restrictions are:
///
/// - Multi-character single-quoted strings are not valid Rust literals; use
/// double quotes.
/// - Luau escapes that Rust string literals do not accept, such as `\a`, `\b`,
/// `\f`, `\v`, `\z`, and decimal escapes other than `\0`, cannot be written
/// directly.
/// - Backtick interpolated strings are not valid Rust tokens.
/// - The `//` floor-division operator starts a Rust comment.
///
/// Captured chunks use an explicit environment. Calling
/// [`Chunk::set_environment`] replaces it, and sandbox behavior for custom
/// environments remains under the embedder's control.
pub use chunk;
/// Registers an inherent `impl` block as part of a derived [`Userdata`] type.
///
/// See the [`Userdata`](derive@Userdata) derive macro for supported receivers,
/// parameters, and attributes.
pub use userdata_impl;
pub use ;
pub use Buffer;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use LightUserdata;
pub use ;
pub use CompilerError;
pub use ObjectLike;
pub use LuaString;
pub use ;
pub use ;
pub use ;
pub use ;
pub use Vector;
/// Allocators accepted by [`Lua::new_with_allocator`].