Add mlua_derive proc macro module
This commit is contained in:
parent
cade76137a
commit
224ed8ff52
|
@ -13,6 +13,11 @@ license = "MIT"
|
|||
# [badges]
|
||||
# travis-ci = { repository = "khvzak/mlua", branch = "master" }
|
||||
|
||||
[workspace]
|
||||
members = [
|
||||
"mlua_derive",
|
||||
]
|
||||
|
||||
[dependencies]
|
||||
libc = { version = "0.2" }
|
||||
num-traits = { version = "0.2.6" }
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
[package]
|
||||
name = "mlua_derive"
|
||||
version = "0.1.0"
|
||||
authors = ["Alex Orlenko <zxteam@protonmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
proc-macro2 = "1.0"
|
||||
quote = "1.0"
|
||||
syn = { version = "1.0", features = ["full"] }
|
|
@ -0,0 +1,35 @@
|
|||
extern crate proc_macro;
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
use proc_macro2::{Ident, Span};
|
||||
use quote::quote_spanned;
|
||||
use syn::{parse_macro_input, spanned::Spanned, AttributeArgs, Error, ItemFn};
|
||||
|
||||
#[proc_macro_attribute]
|
||||
pub fn lua_module(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let args = parse_macro_input!(attr as AttributeArgs);
|
||||
let item = parse_macro_input!(item as ItemFn);
|
||||
|
||||
if args.len() > 0 {
|
||||
let err = Error::new(Span::call_site(), "the number of arguments must be zero")
|
||||
.to_compile_error();
|
||||
return err.into();
|
||||
}
|
||||
|
||||
let span = item.span();
|
||||
let item_name = item.sig.ident.clone();
|
||||
let ext_entrypoint_name = Ident::new(&format!("luaopen_{}", item.sig.ident), Span::call_site());
|
||||
|
||||
let wrapped = quote_spanned! { span =>
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn #ext_entrypoint_name(state: *mut mlua::lua_State) -> std::os::raw::c_int {
|
||||
#item
|
||||
|
||||
mlua::Lua::init_from_ptr(state)
|
||||
.entrypoint1(#item_name)
|
||||
.unwrap()
|
||||
}
|
||||
};
|
||||
|
||||
wrapped.into()
|
||||
}
|
18
src/lua.rs
18
src/lua.rs
|
@ -100,6 +100,18 @@ impl Lua {
|
|||
}
|
||||
}
|
||||
|
||||
// Executes module entrypoint function, which returns only one Value.
|
||||
// The returned value then pushed to the Lua stack.
|
||||
#[doc(hidden)]
|
||||
pub fn entrypoint1<'lua, 'callback, R, F>(&'lua self, func: F) -> Result<c_int>
|
||||
where
|
||||
R: ToLua<'callback>,
|
||||
F: 'static + Send + Fn(&'callback Lua) -> Result<R>,
|
||||
{
|
||||
let cb = self.create_callback(Box::new(move |lua, _| func(lua)?.to_lua_multi(lua)))?;
|
||||
unsafe { self.push_value(cb.call(())?).map(|_| 1) }
|
||||
}
|
||||
|
||||
/// Returns true if the garbage collector is currently running automatically.
|
||||
pub fn gc_is_running(&self) -> bool {
|
||||
unsafe { ffi::lua_gc(self.main_state, ffi::LUA_GCISRUNNING, 0) != 0 }
|
||||
|
@ -718,8 +730,7 @@ impl Lua {
|
|||
}
|
||||
|
||||
// Uses 2 stack spaces, does not call checkstack
|
||||
// TODO: return to original
|
||||
pub unsafe fn push_value(&self, value: Value) -> Result<()> {
|
||||
pub(crate) unsafe fn push_value(&self, value: Value) -> Result<()> {
|
||||
match value {
|
||||
Value::Nil => {
|
||||
ffi::lua_pushnil(self.state);
|
||||
|
@ -770,8 +781,7 @@ impl Lua {
|
|||
}
|
||||
|
||||
// Uses 2 stack spaces, does not call checkstack
|
||||
// TODO: return to original
|
||||
pub unsafe fn pop_value(&self) -> Value {
|
||||
pub(crate) unsafe fn pop_value(&self) -> Value {
|
||||
match ffi::lua_type(self.state, -1) {
|
||||
ffi::LUA_TNIL => {
|
||||
ffi::lua_pop(self.state, 1);
|
||||
|
|
Loading…
Reference in New Issue