mlua/lib.rs
1//! # High-level bindings to Lua
2//!
3//! The `mlua` crate provides safe high-level bindings to the [Lua programming language].
4//!
5//! # The `Lua` object
6//!
7//! The main type exported by this library is the [`Lua`] struct. In addition to methods for
8//! [executing] Lua chunks or [evaluating] Lua expressions, it provides methods for creating Lua
9//! values and accessing the table of [globals].
10//!
11//! # Converting data
12//!
13//! The [`IntoLua`] and [`FromLua`] traits allow conversion from Rust types to Lua values and vice
14//! versa. They are implemented for many data structures found in Rust's standard library.
15//!
16//! For more general conversions, the [`IntoLuaMulti`] and [`FromLuaMulti`] traits allow converting
17//! between Rust types and *any number* of Lua values.
18//!
19//! Most code in `mlua` is generic over implementors of those traits, so in most places the normal
20//! Rust data structures are accepted without having to write any boilerplate.
21//!
22//! # Custom Userdata
23//!
24//! The [`UserData`] trait can be implemented by user-defined types to make them available to Lua.
25//! Methods and operators to be used from Lua can be added using the [`UserDataMethods`] API.
26//! Fields are supported using the [`UserDataFields`] API.
27//!
28//! # Serde support
29//!
30//! The [`LuaSerdeExt`] trait implemented for [`Lua`] allows conversion from Rust types to Lua
31//! values and vice versa using serde. Any user defined data type that implements
32//! [`serde::Serialize`] or [`serde::Deserialize`] can be converted.
33//! For convenience, additional functionality to handle `NULL` values and arrays is provided.
34//!
35//! The [`Value`] enum and other types implement [`serde::Serialize`] trait to support serializing
36//! Lua values into Rust values.
37//!
38//! Requires `feature = "serialize"`.
39//!
40//! # Async/await support
41//!
42//! The [`Lua::create_async_function`] allows creating non-blocking functions that returns
43//! [`Future`]. Lua code with async capabilities can be executed by [`Function::call_async`] family
44//! of functions or polling [`AsyncThread`] using any runtime (eg. Tokio).
45//!
46//! Requires `feature = "async"`.
47//!
48//! # `Send` and `Sync` support
49//!
50//! By default `mlua` is `!Send`. This can be changed by enabling `feature = "send"` that adds
51//! `Send` requirement to Rust functions and [`UserData`] types.
52//!
53//! In this case [`Lua`] object and their types can be send or used from other threads. Internally
54//! access to Lua VM is synchronized using a reentrant mutex that can be locked many times within
55//! the same thread.
56//!
57//! [Lua programming language]: https://www.lua.org/
58//! [executing]: crate::Chunk::exec
59//! [evaluating]: crate::Chunk::eval
60//! [globals]: crate::Lua::globals
61//! [`Future`]: std::future::Future
62//! [`serde::Serialize`]: https://docs.serde.rs/serde/ser/trait.Serialize.html
63//! [`serde::Deserialize`]: https://docs.serde.rs/serde/de/trait.Deserialize.html
64
65// Deny warnings inside doc tests / examples. When this isn't present, rustdoc doesn't show *any*
66// warnings at all.
67#![cfg_attr(docsrs, feature(doc_cfg))]
68#![cfg_attr(not(send), allow(clippy::arc_with_non_send_sync))]
69#![allow(clippy::ptr_eq)]
70
71#[macro_use]
72mod macros;
73
74mod buffer;
75mod chunk;
76mod conversion;
77mod error;
78mod function;
79mod hook;
80#[cfg(feature = "luau")]
81mod luau;
82mod memory;
83mod multi;
84mod scope;
85mod state;
86mod stdlib;
87mod string;
88mod table;
89mod thread;
90mod traits;
91mod types;
92mod userdata;
93mod util;
94mod value;
95mod vector;
96
97pub mod prelude;
98
99pub use bstr::BString;
100pub use ffi::{self, lua_CFunction, lua_State};
101
102pub use crate::chunk::{AsChunk, Chunk, ChunkMode};
103pub use crate::error::{Error, ErrorContext, ExternalError, ExternalResult, Result};
104pub use crate::function::{Function, FunctionInfo};
105pub use crate::hook::{Debug, DebugEvent, DebugNames, DebugSource, DebugStack};
106pub use crate::multi::{MultiValue, Variadic};
107pub use crate::scope::Scope;
108pub use crate::state::{GCMode, Lua, LuaOptions, WeakLua};
109pub use crate::stdlib::StdLib;
110pub use crate::string::{BorrowedBytes, BorrowedStr, String};
111pub use crate::table::{Table, TablePairs, TableSequence};
112pub use crate::thread::{Thread, ThreadStatus};
113pub use crate::traits::{
114 FromLua, FromLuaMulti, IntoLua, IntoLuaMulti, LuaNativeFn, LuaNativeFnMut, ObjectLike,
115};
116pub use crate::types::{
117 AppDataRef, AppDataRefMut, Either, Integer, LightUserData, MaybeSend, Number, RegistryKey, VmState,
118};
119pub use crate::userdata::{
120 AnyUserData, MetaMethod, UserData, UserDataFields, UserDataMetatable, UserDataMethods, UserDataRef,
121 UserDataRefMut, UserDataRegistry,
122};
123pub use crate::value::{Nil, Value};
124
125#[cfg(not(feature = "luau"))]
126pub use crate::hook::HookTriggers;
127
128#[cfg(any(feature = "luau", doc))]
129#[cfg_attr(docsrs, doc(cfg(feature = "luau")))]
130pub use crate::{buffer::Buffer, chunk::Compiler, function::CoverageInfo, vector::Vector};
131
132#[cfg(feature = "async")]
133#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
134pub use crate::{thread::AsyncThread, traits::LuaNativeAsyncFn};
135
136#[cfg(feature = "serialize")]
137#[doc(inline)]
138pub use crate::serde::{de::Options as DeserializeOptions, ser::Options as SerializeOptions, LuaSerdeExt};
139
140#[cfg(feature = "serialize")]
141#[cfg_attr(docsrs, doc(cfg(feature = "serialize")))]
142pub mod serde;
143
144#[cfg(feature = "mlua_derive")]
145#[allow(unused_imports)]
146#[macro_use]
147extern crate mlua_derive;
148
149/// Create a type that implements [`AsChunk`] and can capture Rust variables.
150///
151/// This macro allows to write Lua code directly in Rust code.
152///
153/// Rust variables can be referenced from Lua using `$` prefix, as shown in the example below.
154/// User's Rust types needs to implement [`UserData`] or [`IntoLua`] traits.
155///
156/// Captured variables are **moved** into the chunk.
157///
158/// ```
159/// use mlua::{Lua, Result, chunk};
160///
161/// fn main() -> Result<()> {
162/// let lua = Lua::new();
163/// let name = "Rustacean";
164/// lua.load(chunk! {
165/// print("hello, " .. $name)
166/// }).exec()
167/// }
168/// ```
169///
170/// ## Syntax issues
171///
172/// Since the Rust tokenizer will tokenize Lua code, this imposes some restrictions.
173/// The main thing to remember is:
174///
175/// - Use double quoted strings (`""`) instead of single quoted strings (`''`).
176///
177/// (Single quoted strings only work if they contain a single character, since in Rust,
178/// `'a'` is a character literal).
179///
180/// - Using Lua comments `--` is not desirable in **stable** Rust and can have bad side effects.
181///
182/// This is because procedural macros have Line/Column information available only in
183/// **nightly** Rust. Instead, Lua chunks represented as a big single line of code in stable Rust.
184///
185/// As workaround, Rust comments `//` can be used.
186///
187/// Other minor limitations:
188///
189/// - Certain escape codes in string literals don't work. (Specifically: `\a`, `\b`, `\f`, `\v`,
190/// `\123` (octal escape codes), `\u`, and `\U`).
191///
192/// These are accepted: : `\\`, `\n`, `\t`, `\r`, `\xAB` (hex escape codes), and `\0`.
193///
194/// - The `//` (floor division) operator is unusable, as its start a comment.
195///
196/// Everything else should work.
197#[cfg(feature = "macros")]
198#[cfg_attr(docsrs, doc(cfg(feature = "macros")))]
199pub use mlua_derive::chunk;
200
201/// Derive [`FromLua`] for a Rust type.
202///
203/// Current implementation generate code that takes [`UserData`] value, borrow it (of the Rust type)
204/// and clone.
205#[cfg(feature = "macros")]
206#[cfg_attr(docsrs, doc(cfg(feature = "macros")))]
207pub use mlua_derive::FromLua;
208
209/// Registers Lua module entrypoint.
210///
211/// You can register multiple entrypoints as required.
212///
213/// ```ignore
214/// use mlua::{Lua, Result, Table};
215///
216/// #[mlua::lua_module]
217/// fn my_module(lua: &Lua) -> Result<Table> {
218/// let exports = lua.create_table()?;
219/// exports.set("hello", "world")?;
220/// Ok(exports)
221/// }
222/// ```
223///
224/// Internally in the code above the compiler defines C function `luaopen_my_module`.
225///
226/// You can also pass options to the attribute:
227///
228/// * name - name of the module, defaults to the name of the function
229///
230/// ```ignore
231/// #[mlua::lua_module(name = "alt_module")]
232/// fn my_module(lua: &Lua) -> Result<Table> {
233/// ...
234/// }
235/// ```
236///
237/// * skip_memory_check - skip memory allocation checks for some operations.
238///
239/// In module mode, mlua runs in unknown environment and cannot say are there any memory
240/// limits or not. As result, some operations that require memory allocation runs in
241/// protected mode. Setting this attribute will improve performance of such operations
242/// with risk of having uncaught exceptions and memory leaks.
243///
244/// ```ignore
245/// #[mlua::lua_module(skip_memory_check)]
246/// fn my_module(lua: &Lua) -> Result<Table> {
247/// ...
248/// }
249/// ```
250#[cfg(all(feature = "mlua_derive", any(feature = "module", doc)))]
251#[cfg_attr(docsrs, doc(cfg(feature = "module")))]
252pub use mlua_derive::lua_module;
253
254#[cfg(all(feature = "module", feature = "send"))]
255compile_error!("`send` feature is not supported in module mode");
256
257pub(crate) mod private {
258 use super::*;
259
260 pub trait Sealed {}
261
262 impl Sealed for Error {}
263 impl<T> Sealed for std::result::Result<T, Error> {}
264 impl Sealed for Lua {}
265 impl Sealed for Table {}
266 impl Sealed for AnyUserData {}
267}