Update to use hlist_macro for hlist macros.
You will type hlist! hlist_pat! and HList! so often that every character counts. Apologize for the API churn in the README.
This commit is contained in:
parent
9bed8f499f
commit
b15ee9053e
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "rlua"
|
name = "rlua"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
authors = ["kyren <catherine@chucklefish.org>"]
|
authors = ["kyren <catherine@chucklefish.org>"]
|
||||||
repository = "https://github.com/chucklefish/rlua"
|
repository = "https://github.com/chucklefish/rlua"
|
||||||
description = "High level bindings to Lua 5.3"
|
description = "High level bindings to Lua 5.3"
|
||||||
|
@ -9,7 +9,8 @@ keywords = ["lua"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
gcc = "*"
|
gcc = "0.3"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
error-chain = "*"
|
hlist-macro = "0.1"
|
||||||
|
error-chain = "0.10"
|
||||||
|
|
|
@ -65,6 +65,12 @@ in rustc. For example:
|
||||||
See [this reddit discussion](http://www.reddit.com/r/rust/comments/5yujt6/) for
|
See [this reddit discussion](http://www.reddit.com/r/rust/comments/5yujt6/) for
|
||||||
details of the current lifetime problem with callback wrapping.
|
details of the current lifetime problem with callback wrapping.
|
||||||
|
|
||||||
|
## API Stability or lack thereof
|
||||||
|
|
||||||
|
This library is very much Work In Progress, so there may be a lot of API churn.
|
||||||
|
I will try to follow a pre-1.0 semver (if such a thing exists), but that means
|
||||||
|
there will just be a large number of API bumps.
|
||||||
|
|
||||||
## Safety
|
## Safety
|
||||||
|
|
||||||
My *goal* is complete safety, it should not be possible to cause undefined
|
My *goal* is complete safety, it should not be possible to cause undefined
|
||||||
|
@ -85,4 +91,5 @@ The library currently attempts to handle each of these situations, but there
|
||||||
are so many ways to cause unsafety with Lua that it just needs more testing.
|
are so many ways to cause unsafety with Lua that it just needs more testing.
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
Please look at the examples [here](examples/examples.rs).
|
Please look at the examples [here](examples/examples.rs).
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
extern crate hlist_macro;
|
||||||
extern crate rlua;
|
extern crate rlua;
|
||||||
|
|
||||||
use rlua::*;
|
use rlua::*;
|
||||||
|
@ -70,7 +71,7 @@ fn examples() -> LuaResult<()> {
|
||||||
// is one way to call a function with multiple parameters:
|
// is one way to call a function with multiple parameters:
|
||||||
|
|
||||||
print
|
print
|
||||||
.call::<_, ()>(lua_multi!["hello", "again", "from", "rust"])?;
|
.call::<_, ()>(hlist!["hello", "again", "from", "rust"])?;
|
||||||
|
|
||||||
// You can bind rust functions to lua as well
|
// You can bind rust functions to lua as well
|
||||||
|
|
||||||
|
@ -80,7 +81,7 @@ fn examples() -> LuaResult<()> {
|
||||||
// parts. Due to lifetime type signature limitations, this cannot be done automatically from the
|
// parts. Due to lifetime type signature limitations, this cannot be done automatically from the
|
||||||
// function signature, but this will be fixed with ATCs. Notice the use of the hlist
|
// function signature, but this will be fixed with ATCs. Notice the use of the hlist
|
||||||
// macros again.
|
// macros again.
|
||||||
let lua_multi_pat![list1, list2] = lua.unpack::<LuaMulti![Vec<String>, Vec<String>]>(args)?;
|
let hlist_pat![list1, list2] = lua.unpack::<HList![Vec<String>, Vec<String>]>(args)?;
|
||||||
|
|
||||||
// This function just checks whether two string lists are equal, and in an inefficient way.
|
// This function just checks whether two string lists are equal, and in an inefficient way.
|
||||||
// Results are returned with lua.pack, which takes any number of values and turns them back
|
// Results are returned with lua.pack, which takes any number of values and turns them back
|
||||||
|
@ -119,14 +120,14 @@ fn examples() -> LuaResult<()> {
|
||||||
});
|
});
|
||||||
|
|
||||||
methods.add_meta_function(LuaMetaMethod::Add, |lua, params| {
|
methods.add_meta_function(LuaMetaMethod::Add, |lua, params| {
|
||||||
let lua_multi_pat![vec1, vec2] = lua.unpack::<LuaMulti![Vec2, Vec2]>(params)?;
|
let hlist_pat![vec1, vec2] = lua.unpack::<HList![Vec2, Vec2]>(params)?;
|
||||||
lua.pack(Vec2(vec1.0 + vec2.0, vec1.1 + vec2.1))
|
lua.pack(Vec2(vec1.0 + vec2.0, vec1.1 + vec2.1))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let vec2_constructor = lua.create_function(|lua, args| {
|
let vec2_constructor = lua.create_function(|lua, args| {
|
||||||
let lua_multi_pat![x, y] = lua.unpack::<LuaMulti![f32, f32]>(args)?;
|
let hlist_pat![x, y] = lua.unpack::<HList![f32, f32]>(args)?;
|
||||||
lua.pack(Vec2(x, y))
|
lua.pack(Vec2(x, y))
|
||||||
})?;
|
})?;
|
||||||
lua.set("vec2", vec2_constructor)?;
|
lua.set("vec2", vec2_constructor)?;
|
||||||
|
|
10
src/lib.rs
10
src/lib.rs
|
@ -1,10 +1,14 @@
|
||||||
|
#[cfg(test)]
|
||||||
|
#[macro_use]
|
||||||
|
extern crate hlist_macro;
|
||||||
|
|
||||||
|
#[cfg(not(test))]
|
||||||
|
extern crate hlist_macro;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate error_chain;
|
extern crate error_chain;
|
||||||
|
|
||||||
|
|
||||||
pub mod ffi;
|
pub mod ffi;
|
||||||
#[macro_use]
|
|
||||||
mod macros;
|
|
||||||
mod util;
|
mod util;
|
||||||
mod error;
|
mod error;
|
||||||
mod lua;
|
mod lua;
|
||||||
|
|
32
src/multi.rs
32
src/multi.rs
|
@ -1,12 +1,8 @@
|
||||||
|
use hlist_macro::{HNil, HCons};
|
||||||
|
|
||||||
use error::*;
|
use error::*;
|
||||||
use lua::*;
|
use lua::*;
|
||||||
|
|
||||||
#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
|
||||||
pub struct LNil;
|
|
||||||
|
|
||||||
#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
|
||||||
pub struct LCons<H, T>(pub H, pub T);
|
|
||||||
|
|
||||||
impl<'lua> ToLuaMulti<'lua> for () {
|
impl<'lua> ToLuaMulti<'lua> for () {
|
||||||
fn to_lua_multi(self, _: &'lua Lua) -> LuaResult<LuaMultiValue> {
|
fn to_lua_multi(self, _: &'lua Lua) -> LuaResult<LuaMultiValue> {
|
||||||
Ok(LuaMultiValue::new())
|
Ok(LuaMultiValue::new())
|
||||||
|
@ -63,32 +59,32 @@ impl<'lua, T: FromLua<'lua>> FromLuaMulti<'lua> for LuaVariadic<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'lua> ToLuaMulti<'lua> for LNil {
|
impl<'lua> ToLuaMulti<'lua> for HNil {
|
||||||
fn to_lua_multi(self, _: &'lua Lua) -> LuaResult<LuaMultiValue<'lua>> {
|
fn to_lua_multi(self, _: &'lua Lua) -> LuaResult<LuaMultiValue<'lua>> {
|
||||||
Ok(LuaMultiValue::new())
|
Ok(LuaMultiValue::new())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'lua> FromLuaMulti<'lua> for LNil {
|
impl<'lua> FromLuaMulti<'lua> for HNil {
|
||||||
fn from_lua_multi(_: LuaMultiValue<'lua>, _: &'lua Lua) -> LuaResult<Self> {
|
fn from_lua_multi(_: LuaMultiValue<'lua>, _: &'lua Lua) -> LuaResult<Self> {
|
||||||
Ok(LNil)
|
Ok(HNil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'lua, T: ToLuaMulti<'lua>> ToLuaMulti<'lua> for LCons<T, LNil> {
|
impl<'lua, T: ToLuaMulti<'lua>> ToLuaMulti<'lua> for HCons<T, HNil> {
|
||||||
fn to_lua_multi(self, lua: &'lua Lua) -> LuaResult<LuaMultiValue<'lua>> {
|
fn to_lua_multi(self, lua: &'lua Lua) -> LuaResult<LuaMultiValue<'lua>> {
|
||||||
self.0.to_lua_multi(lua)
|
self.0.to_lua_multi(lua)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'lua, T: FromLuaMulti<'lua>> FromLuaMulti<'lua> for LCons<T, LNil> {
|
impl<'lua, T: FromLuaMulti<'lua>> FromLuaMulti<'lua> for HCons<T, HNil> {
|
||||||
fn from_lua_multi(values: LuaMultiValue<'lua>, lua: &'lua Lua) -> LuaResult<Self> {
|
fn from_lua_multi(values: LuaMultiValue<'lua>, lua: &'lua Lua) -> LuaResult<Self> {
|
||||||
Ok(LCons(T::from_lua_multi(values, lua)?, LNil))
|
Ok(HCons(T::from_lua_multi(values, lua)?, HNil))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'lua, H: ToLua<'lua>, A, B> ToLuaMulti<'lua> for LCons<H, LCons<A, B>>
|
impl<'lua, H: ToLua<'lua>, A, B> ToLuaMulti<'lua> for HCons<H, HCons<A, B>>
|
||||||
where LCons<A, B>: ToLuaMulti<'lua>
|
where HCons<A, B>: ToLuaMulti<'lua>
|
||||||
{
|
{
|
||||||
fn to_lua_multi(self, lua: &'lua Lua) -> LuaResult<LuaMultiValue<'lua>> {
|
fn to_lua_multi(self, lua: &'lua Lua) -> LuaResult<LuaMultiValue<'lua>> {
|
||||||
let mut results = self.1.to_lua_multi(lua)?;
|
let mut results = self.1.to_lua_multi(lua)?;
|
||||||
|
@ -97,12 +93,12 @@ impl<'lua, H: ToLua<'lua>, A, B> ToLuaMulti<'lua> for LCons<H, LCons<A, B>>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'lua, H: FromLua<'lua>, A, B> FromLuaMulti<'lua> for LCons<H, LCons<A, B>>
|
impl<'lua, H: FromLua<'lua>, A, B> FromLuaMulti<'lua> for HCons<H, HCons<A, B>>
|
||||||
where LCons<A, B>: FromLuaMulti<'lua>
|
where HCons<A, B>: FromLuaMulti<'lua>
|
||||||
{
|
{
|
||||||
fn from_lua_multi(mut values: LuaMultiValue<'lua>, lua: &'lua Lua) -> LuaResult<Self> {
|
fn from_lua_multi(mut values: LuaMultiValue<'lua>, lua: &'lua Lua) -> LuaResult<Self> {
|
||||||
let val = H::from_lua(values.pop_front().unwrap_or(LuaNil), lua)?;
|
let val = H::from_lua(values.pop_front().unwrap_or(LuaNil), lua)?;
|
||||||
let res = LCons::<A, B>::from_lua_multi(values, lua)?;
|
let res = HCons::<A, B>::from_lua_multi(values, lua)?;
|
||||||
Ok(LCons(val, res))
|
Ok(HCons(val, res))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
16
src/tests.rs
16
src/tests.rs
|
@ -86,7 +86,7 @@ fn test_function() {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let concat = lua.get::<_, LuaFunction>("concat").unwrap();
|
let concat = lua.get::<_, LuaFunction>("concat").unwrap();
|
||||||
assert_eq!(concat.call::<_, String>(lua_multi!["foo", "bar"]).unwrap(),
|
assert_eq!(concat.call::<_, String>(hlist!["foo", "bar"]).unwrap(),
|
||||||
"foobar");
|
"foobar");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,8 +108,8 @@ fn test_bind() {
|
||||||
let mut concat = lua.get::<_, LuaFunction>("concat").unwrap();
|
let mut concat = lua.get::<_, LuaFunction>("concat").unwrap();
|
||||||
concat = concat.bind("foo").unwrap();
|
concat = concat.bind("foo").unwrap();
|
||||||
concat = concat.bind("bar").unwrap();
|
concat = concat.bind("bar").unwrap();
|
||||||
concat = concat.bind(lua_multi!["baz", "baf"]).unwrap();
|
concat = concat.bind(hlist!["baz", "baf"]).unwrap();
|
||||||
assert_eq!(concat.call::<_, String>(lua_multi!["hi", "wut"]).unwrap(),
|
assert_eq!(concat.call::<_, String>(hlist!["hi", "wut"]).unwrap(),
|
||||||
"foobarbazbafhiwut");
|
"foobarbazbafhiwut");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,11 +202,11 @@ fn test_metamethods() {
|
||||||
fn add_methods(methods: &mut LuaUserDataMethods<Self>) {
|
fn add_methods(methods: &mut LuaUserDataMethods<Self>) {
|
||||||
methods.add_method("get", |lua, data, _| lua.pack(data.0));
|
methods.add_method("get", |lua, data, _| lua.pack(data.0));
|
||||||
methods.add_meta_function(LuaMetaMethod::Add, |lua, args| {
|
methods.add_meta_function(LuaMetaMethod::Add, |lua, args| {
|
||||||
let lua_multi_pat![lhs, rhs] = lua.unpack::<LuaMulti![UserData, UserData]>(args)?;
|
let hlist_pat![lhs, rhs] = lua.unpack::<HList![UserData, UserData]>(args)?;
|
||||||
lua.pack(UserData(lhs.0 + rhs.0))
|
lua.pack(UserData(lhs.0 + rhs.0))
|
||||||
});
|
});
|
||||||
methods.add_meta_function(LuaMetaMethod::Sub, |lua, args| {
|
methods.add_meta_function(LuaMetaMethod::Sub, |lua, args| {
|
||||||
let lua_multi_pat![lhs, rhs] = lua.unpack::<LuaMulti![UserData, UserData]>(args)?;
|
let hlist_pat![lhs, rhs] = lua.unpack::<HList![UserData, UserData]>(args)?;
|
||||||
lua.pack(UserData(lhs.0 - rhs.0))
|
lua.pack(UserData(lhs.0 - rhs.0))
|
||||||
});
|
});
|
||||||
methods.add_meta_method(LuaMetaMethod::Index, |lua, data, args| {
|
methods.add_meta_method(LuaMetaMethod::Index, |lua, data, args| {
|
||||||
|
@ -282,11 +282,11 @@ fn test_lua_multi() {
|
||||||
let concat = lua.get::<_, LuaFunction>("concat").unwrap();
|
let concat = lua.get::<_, LuaFunction>("concat").unwrap();
|
||||||
let mreturn = lua.get::<_, LuaFunction>("mreturn").unwrap();
|
let mreturn = lua.get::<_, LuaFunction>("mreturn").unwrap();
|
||||||
|
|
||||||
assert_eq!(concat.call::<_, String>(lua_multi!["foo", "bar"]).unwrap(),
|
assert_eq!(concat.call::<_, String>(hlist!["foo", "bar"]).unwrap(),
|
||||||
"foobar");
|
"foobar");
|
||||||
let lua_multi_pat![a, b] = mreturn.call::<_, LuaMulti![u64, u64]>(lua_multi![]).unwrap();
|
let hlist_pat![a, b] = mreturn.call::<_, HList![u64, u64]>(hlist![]).unwrap();
|
||||||
assert_eq!((a, b), (1, 2));
|
assert_eq!((a, b), (1, 2));
|
||||||
let lua_multi_pat![a, b, LuaVariadic(v)] = mreturn.call::<_, LuaMulti![u64, u64, LuaVariadic<u64>]>(lua_multi![]).unwrap();
|
let hlist_pat![a, b, LuaVariadic(v)] = mreturn.call::<_, HList![u64, u64, LuaVariadic<u64>]>(hlist![]).unwrap();
|
||||||
assert_eq!((a, b), (1, 2));
|
assert_eq!((a, b), (1, 2));
|
||||||
assert_eq!(v, vec![3, 4, 5, 6]);
|
assert_eq!(v, vec![3, 4, 5, 6]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,12 @@ use std::panic::{catch_unwind, resume_unwind, UnwindSafe};
|
||||||
use ffi;
|
use ffi;
|
||||||
use error::{LuaResult, LuaError, LuaErrorKind};
|
use error::{LuaResult, LuaError, LuaErrorKind};
|
||||||
|
|
||||||
|
macro_rules! cstr {
|
||||||
|
($s:expr) => (
|
||||||
|
concat!($s, "\0") as *const str as *const [c_char] as *const c_char
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Run an operation on a lua_State and automatically clean up the stack before returning. Takes
|
// Run an operation on a lua_State and automatically clean up the stack before returning. Takes
|
||||||
// the lua_State, the expected stack size change, and an operation to run. If the operation
|
// the lua_State, the expected stack size change, and an operation to run. If the operation
|
||||||
// results in success, then the stack is inspected to make sure the change in stack size matches
|
// results in success, then the stack is inspected to make sure the change in stack size matches
|
||||||
|
@ -139,7 +145,7 @@ pub unsafe fn pcall_with_traceback(state: *mut ffi::lua_State,
|
||||||
if !s.is_null() {
|
if !s.is_null() {
|
||||||
ffi::luaL_traceback(state, state, s, 0);
|
ffi::luaL_traceback(state, state, s, 0);
|
||||||
} else {
|
} else {
|
||||||
ffi::luaL_traceback(state, state, lua_cstr!("<unprintable error>"), 0);
|
ffi::luaL_traceback(state, state, cstr!("<unprintable error>"), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
1
|
1
|
||||||
|
|
Loading…
Reference in New Issue