5 releases

0.1.4 Jun 28, 2020
0.1.3 Jun 6, 2020
0.1.2 Jun 6, 2020
0.1.1 Jun 3, 2020
0.1.0 Jun 2, 2020

#8 in #rlua

MIT license

7KB

rlua-builders

Travis (.org) Crates.io

This package allows Rust structs/enums to be easily created from Lua.

enum Valuables {
    Coins(u32),
    Book {name: String},
    Knowledge,
}

Can then be created from Lua as:

local a = Valuables.Coins(12)
local b = Valuables.Knowledge
local c = Valuables.Book { name = "A Dance with Dragons" }

See the documentation for more information.


lib.rs:

The rlua-builders crate provides helpers for Rust/Lua interop using rlua. That means creating Rust struct/enums from Lua with almost the same syntax as in Rust!

This crate itself only provides a trait definition, but using the (default) derive feature provides derive macros to automatically implement the defined trait for any struct or enum, as long as it has UserData implemented for it (for which a derive macro is also provided). After that, simply call StructOrEnum::builder(ctx) to create a builder for that struct or enum.

What do these builders look like?

  • For unit structs: A builder is simply the unit value itself, which can be converted to Lua since the struct implements UserData.
  • For tuple structs: A builder is a lua function that receives the tuple arguments in order and returns the userdata for the struct.
  • For normal structs: A builder is a lua function that receives a single table with the named arguments to the struct.
  • For enums: A builder is a table where each field is a builder for each of the enum's variants, and each of them works the same way as the struct builders defined above.

Examples:

This shows how to derive and use LuaBuilder and UserData on a simple struct. By default the derive macros are imported with rlua-builders. See rlua for more documentation on how to interop with Lua.

use rlua_builders::{LuaBuilder, UserData};

#[derive(LuaBuilder, UserData, Clone, PartialEq, Debug)]
struct Person {
    name: String,
    age: u8,
}

let p = rlua::Lua::new().context(|ctx| {
    ctx.globals().set("Person", Person::builder(ctx)?)?;
    ctx.load(r#"Person { name = "Yan", age = 24 }"#).eval::<Person>()
}).unwrap();

assert_eq!(p, Person {name: "Yan".to_owned(), age: 24})

Enums work in a similar way, except their constructor is a table where each function is equivalent to a struct builder.

Additionally, you can use #[default=VALUE] to specify a default value for the field. That means if nil is specified in Lua, then instead that default will be used, without needing to manually use Option + unwrap_or.

#[derive(LuaBuilder, UserData, Clone)]
enum Valuables {
    Coins(u32),
    Book {
        name: String,
        #[default=true]
        read: bool,
    },
    Knowledge,
}

If later binded to lua

ctx.globals().set("Valuables", Valuables::builder(ctx)?)?;

Can be used in a very similar way to Rust

local a = Valuables.Coins(12)
local b = Valuables.Knowledge
local c = Valuables.Book { name = "A Dance with Dragons" }

Dependencies

~0.7–1.2MB
~21K SLoC