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