rlua_builders/
lib.rs

1//! The rlua-builders crate provides helpers for Rust/Lua interop using
2//! [`rlua`]. That means creating Rust struct/enums from Lua with almost the
3//! same syntax as in Rust!
4//!
5//! This crate itself only provides a trait definition, but using the (default) `derive`
6//! feature provides derive macros to automatically implement the defined trait for
7//! any struct or enum, as long as it has [`UserData`] implemented for it (for which a derive
8//! macro is also provided). After that, simply call `StructOrEnum::builder(ctx)` to create a
9//! builder for that struct or enum.
10//!
11//! ## What do these builders look like?
12//! - For [unit structs]: A builder is simply the unit value itself, which can be converted to
13//! Lua since the struct implements [`UserData`].
14//! - For [tuple structs]: A builder is a lua function that receives the tuple arguments in order
15//! and returns the userdata for the struct.
16//! - For [normal structs]: A builder is a lua function that receives a single table with
17//! the named arguments to the struct.
18//! - For [enums]: A builder is a table where each field is a builder for each of the enum's
19//! variants, and each of them works the same way as the struct builders defined above.
20//!
21//! ## Examples:
22//! This shows how to derive and use [`LuaBuilder`] and [`UserData`] on a simple struct. By default
23//! the derive macros are imported with `rlua-builders`. See [`rlua`] for more documentation on how
24//! to interop with Lua.
25//! ```
26//! use rlua_builders::{LuaBuilder, UserData};
27//!
28//! #[derive(LuaBuilder, UserData, Clone, PartialEq, Debug)]
29//! struct Person {
30//!     name: String,
31//!     age: u8,
32//! }
33//!
34//! let p = rlua::Lua::new().context(|ctx| {
35//!     ctx.globals().set("Person", Person::builder(ctx)?)?;
36//!     ctx.load(r#"Person { name = "Yan", age = 24 }"#).eval::<Person>()
37//! }).unwrap();
38//!
39//! assert_eq!(p, Person {name: "Yan".to_owned(), age: 24})
40//! ```
41//!
42//! Enums work in a similar way, except their constructor is a table where each function
43//! is equivalent to a struct builder.
44//!
45//! Additionally, you can use `#[default=VALUE]` to specify a default value for the field.
46//! That means if nil is specified in Lua, then instead that default will be used, without
47//! needing to manually use `Option` + `unwrap_or`.
48//!
49//! ```
50//! # use rlua::UserData;
51//! # use rlua_builders::*;
52//! #[derive(LuaBuilder, UserData, Clone)]
53//! enum Valuables {
54//!     Coins(u32),
55//!     Book {
56//!         name: String,
57//!         #[default=true]
58//!         read: bool,
59//!     },
60//!     Knowledge,
61//! }
62//! ```
63//! If later binded to lua
64//! ```
65//! # use rlua::UserData;
66//! # use rlua_builders::*;
67//! # #[derive(LuaBuilder, UserData, Clone)]
68//! # enum Valuables {}
69//! # rlua::Lua::new().context::<_, rlua::Result<()>>(|ctx| {
70//! ctx.globals().set("Valuables", Valuables::builder(ctx)?)?;
71//! # Ok(())
72//! # }).unwrap();
73//! ```
74//! Can be used in a very similar way to Rust
75//! ```lua
76//! local a = Valuables.Coins(12)
77//! local b = Valuables.Knowledge
78//! local c = Valuables.Book { name = "A Dance with Dragons" }
79//! ```
80//!
81//! [`UserData`]: rlua::UserData
82//! [`rlua-builders-derive`]: https://crates.io/crates/rlua-builders-derive
83//! [unit structs]: http://doc.rust-lang.org/1.43.1/book/ch05-01-defining-structs.html#unit-like-structs-without-any-fields
84//! [tuple structs]: https://doc.rust-lang.org/1.43.1/book/ch05-01-defining-structs.html#using-tuple-structs-without-named-fields-to-create-different-types
85//! [normal structs]: https://doc.rust-lang.org/1.43.1/book/ch05-01-defining-structs.html#defining-and-instantiating-structs
86//! [enums]: https://doc.rust-lang.org/1.43.1/book/ch06-01-defining-an-enum.html#defining-an-enum
87use rlua::{Context, Result, ToLua, UserData};
88
89/// A struct or enum with this Trait provides a Lua builder.
90///
91/// Should not be implemented manually, instead use the [`rlua-builders-derive`] crate
92/// to derive it automatically for any struct or enum.
93///
94/// [`rlua-builders-derive`]: https://crates.io/crates/rlua-builders-derive
95pub trait LuaBuilder<'s, T: ToLua<'s>>: UserData + Clone {
96    /// Create a Lua builder for this type
97    fn builder(ctx: Context<'s>) -> Result<T>;
98}
99
100#[cfg(feature = "derive")]
101pub use rlua_builders_derive::*;