mlua

![Build Status] ![Latest Version] ![API Documentation]

Guided Tour

A fork of rlua 0.15 which provides a high level interface between Rust and Lua. Unlike rlua , mlua supports Lua 5.1 (including LuaJIT) and 5.3. The mlua goal is to be an easy to use, practical and flexible API between Rust and Lua but not always 100% safe due to the Lua VM nature. Also, mlua provides a way to write native lua modules in Rust.

Usage

standalone mode

Add to Cargo.toml :

toml [dependencies] mlua = "0.1"

main.rs

``` rust use mlua::prelude::*;

fn main() -> LuaResult<()> { let lua = Lua::new();

let map_table = lua.create_table()?;
map_table.set(1, "one")?;
map_table.set("two", 2)?;

lua.globals().set("map_table", map_table)?;

lua.load("for k,v in pairs(map_table) do print(k,v) end").exec()?;

Ok(())

} ```

module mode

Add to Cargo.toml :

``` toml [lib] crate-type = ["cdylib"]

[dependencies] mlua = "0.1" mlua_derive = "0.1" ```

lib.rs :

``` rust

[macro_use]

extern crate mlua_derive; use mlua::prelude::*;

fn hello(_: &Lua, name: String) -> LuaResult<()> { println!("hello, {}!", name); Ok(()) }

[lua_module]

fn mymodule(lua: &Lua) -> LuaResult { let exports = lua.createtable()?; exports.set("hello", lua.create_function(hello)?)?; Ok(exports) } ```

And then (macos example):

sh $ cargo build $ ln -s ./target/debug/libmy_module.dylib ./my_module.so $ lua5.3 -e 'require("my_module").hello("world")'

Safety

One of the mlua goals is to provide safe API between Rust and Lua. Every place where the Lua C API may trigger an error longjmp in any way is protected by lua_pcall , and the user of the library is protected from directly interacting with unsafe things like the Lua stack, and there is overhead associated with this safety.

Unfortunately, mlua does not provide absolute safety even without using unsafe . This library contains a huge amount of unsafe code. There are almost certainly bugs still lurking in this library! It is surprisingly, fiendishly difficult to use the Lua C API without the potential for unsafety.

Panic handling

mlua wraps panics that are generated inside Rust callbacks in a regular Lua error. Panics could be resumed then by propagating the Lua error to Rust code.

For example: ``` rust let lua = Lua::new(); let f = lua.createfunction(|, ()| -> LuaResult<()> { panic!("test panic"); })?; lua.globals().set("rust_func", f)?;

let _ = lua.load(r#"
    local status, err = pcall(rust_func)
    print(err) -- prints: test panic
    error(err) -- propagate panic
"#).exec();

panic!("must be never executed")

```

mlua should also be panic safe in another way as well, which is that any Lua instances or handles remains usable after a user generated panic, and such panics should not break internal invariants or leak Lua stack space. This is mostly important to safely use mlua types in Drop impls, as you should not be using panics for general error handling.

Below is a list of mlua behaviors that should be considered a bug. If you encounter them, a bug report would be very welcome:

License

This project is licensed under the MIT license