1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
/// Write a lua function similar to Rust's syntax
///
/// # Example
///
/// ```
/// use mlua::Lua;
///
/// let lua = Lua::new();
/// lua.create_function(|lua, ()| Ok(()))
/// ```
///
/// vs
///
/// ```
/// use mlua_extras::{mlua::Lua, function};
///
/// let lua = Lua::new();
/// function! {
/// lua fn name(lua) {
/// Ok(())
/// }
/// }
/// ```
///
/// It can also be used to asssign functions to nested tables. This requires the `LuaExtras` crate
/// when you start with lua as the source, and the `Require` trait when using any other table as
/// the source.
///
/// ```
/// use mlua::{Lua, Table};
///
/// let lua = Lua::new();
/// lua.globals().get::<_, Table>("nested")?.set("name", lua.create_function(|lua, ()| Ok(()))?)?;
///
/// let nested = lua.globals().get::<_, Table>("deep")?.get::<_, Table>("nested");
/// nested.set("name", lua.create_function(|lua, ()| Ok(())))?;
/// ```
///
/// vs
///
/// ```
/// use mlua_extras::{
/// mlua::{Lua, Table},
/// extras::{LuaExtras, Require},
/// };
///
/// let lua = Lua::new();
/// function! {
/// lua fn lua::nested.name(lua) {
/// Ok(())
/// }
/// }
///
/// let nested = lua.globals().get::<_, Table>("deep")?;
/// function! {
/// lua fn deep::nested.name(lua) {
/// Ok(())
/// }
/// }
/// ```
#[macro_export]
macro_rules! function {
{
$(#[$($attr: tt)*])*
$lua: ident fn $name: ident(
$l: ident $(: $lty: ty)?
$(, $arg: ident : $aty: ty)*
) $(-> $ret: ty)? {
$($body: tt)*
}
} => {
$lua.create_function(|$l $(: $lty)?, ($($arg,)*): ($($aty,)*)| $(-> $ret)? {
$($body)*
})
};
{
$(#[$($attr: tt)*])*
$lua: ident fn $source: ident $(::$inner: ident)* . $name: ident(
$l: ident $(: $lty: ty)?
$(, $arg: ident : $aty: ty)*
) $(-> $ret: ty)? {
$($body: tt)*
}
} => {
{
match $source.require::<mlua::Table>(stringify!($($inner.)*)) $(-> $ret: ty)? {
Ok(table) => match $lua.create_function(|$l$(: $lty)?, ($($arg,)*): ($($aty,)*)| $(-> $ret)? {
$($body)*
}) {
Ok(fun) => table.set(stringify!($name), fun),
Err(err) => Err(err)
}
Err(err) => Err(err)
}
}
};
}