rustfmt changes

This commit is contained in:
kyren 2017-06-15 10:26:39 -04:00
parent 8440298e71
commit 0022057058
6 changed files with 355 additions and 229 deletions

View File

@ -80,8 +80,9 @@ fn examples() -> LuaResult<()> {
// Heterogeneous Lists. This is one way to call a function with multiple
// parameters:
print
.call::<_, ()>(hlist!["hello", "again", "from", "rust"])?;
print.call::<_, ()>(
hlist!["hello", "again", "from", "rust"],
)?;
// You can bind rust functions to lua as well
@ -106,16 +107,24 @@ fn examples() -> LuaResult<()> {
// You can also accept variadic arguments to rust functions
let join = lua.create_function(|lua, args| {
let strings = lua.unpack::<LuaVariadic<String>>(args)?.0;
// (This is quadratic!, it's just an example!)
lua.pack(strings.iter().fold("".to_owned(), |a, b| a + b))
})?;
let strings = lua.unpack::<LuaVariadic<String>>(args)?.0;
// (This is quadratic!, it's just an example!)
lua.pack(strings.iter().fold("".to_owned(), |a, b| a + b))
})?;
globals.set("join", join)?;
assert_eq!(lua.eval::<bool>(r#"check_equal({"a", "b", "c"}, {"a", "b", "c"})"#)?,
true);
assert_eq!(lua.eval::<bool>(r#"check_equal({"a", "b", "c"}, {"d", "e", "f"})"#)?,
false);
assert_eq!(
lua.eval::<bool>(
r#"check_equal({"a", "b", "c"}, {"a", "b", "c"})"#,
)?,
true
);
assert_eq!(
lua.eval::<bool>(
r#"check_equal({"a", "b", "c"}, {"d", "e", "f"})"#,
)?,
false
);
assert_eq!(lua.eval::<String>(r#"join("a", "b", "c")"#)?, "abc");
// You can create userdata with methods and metamethods defined on them.
@ -145,8 +154,10 @@ fn examples() -> LuaResult<()> {
})?;
globals.set("vec2", vec2_constructor)?;
assert_eq!(lua.eval::<f32>("(vec2(1, 2) + vec2(2, 2)):magnitude()")?,
5.0);
assert_eq!(
lua.eval::<f32>("(vec2(1, 2) + vec2(2, 2)):magnitude()")?,
5.0
);
Ok(())
}

View File

@ -56,7 +56,8 @@ pub trait LuaExternalResult<T> {
}
impl<T, E> LuaExternalResult<T> for Result<T, E>
where E: 'static + Error + Send
where
E: 'static + Error + Send,
{
fn to_lua_err(self) -> LuaResult<T> {
self.map_err(|e| LuaExternalError(Box::new(e)).into())

View File

@ -47,18 +47,21 @@ pub const LUA_TTHREAD: c_int = 8;
extern "C" {
pub fn lua_close(state: *mut lua_State);
pub fn lua_callk(state: *mut lua_State,
nargs: c_int,
nresults: c_int,
ctx: lua_KContext,
k: Option<lua_KFunction>);
pub fn lua_pcallk(state: *mut lua_State,
nargs: c_int,
nresults: c_int,
msgh: c_int,
ctx: lua_KContext,
k: Option<lua_KFunction>)
-> c_int;
pub fn lua_callk(
state: *mut lua_State,
nargs: c_int,
nresults: c_int,
ctx: lua_KContext,
k: Option<lua_KFunction>,
);
pub fn lua_pcallk(
state: *mut lua_State,
nargs: c_int,
nresults: c_int,
msgh: c_int,
ctx: lua_KContext,
k: Option<lua_KFunction>,
) -> c_int;
pub fn lua_resume(state: *mut lua_State, from: *mut lua_State, nargs: c_int) -> c_int;
pub fn lua_status(state: *mut lua_State) -> c_int;
@ -115,19 +118,22 @@ extern "C" {
pub fn luaL_newstate() -> *mut lua_State;
pub fn luaL_openlibs(state: *mut lua_State);
pub fn luaL_loadbufferx(state: *mut lua_State,
buf: *const c_char,
size: usize,
name: *const c_char,
mode: *const c_char)
-> c_int;
pub fn luaL_loadbufferx(
state: *mut lua_State,
buf: *const c_char,
size: usize,
name: *const c_char,
mode: *const c_char,
) -> c_int;
pub fn luaL_ref(state: *mut lua_State, table: c_int) -> c_int;
pub fn luaL_unref(state: *mut lua_State, table: c_int, lref: c_int);
pub fn luaL_checkstack(state: *mut lua_State, size: c_int, msg: *const c_char);
pub fn luaL_traceback(push_state: *mut lua_State,
state: *mut lua_State,
msg: *const c_char,
level: c_int);
pub fn luaL_traceback(
push_state: *mut lua_State,
state: *mut lua_State,
msg: *const c_char,
level: c_int,
);
pub fn luaL_len(push_state: *mut lua_State, index: c_int) -> lua_Integer;
}
@ -228,11 +234,12 @@ pub unsafe fn lua_call(state: *mut lua_State, nargs: c_int, nresults: c_int) {
lua_callk(state, nargs, nresults, ptr::null_mut(), None)
}
pub unsafe fn lua_pcall(state: *mut lua_State,
nargs: c_int,
nresults: c_int,
msgh: c_int)
-> c_int {
pub unsafe fn lua_pcall(
state: *mut lua_State,
nargs: c_int,
nresults: c_int,
msgh: c_int,
) -> c_int {
lua_pcallk(state, nargs, nresults, msgh, ptr::null_mut(), None)
}
@ -241,10 +248,11 @@ pub unsafe fn lua_replace(state: *mut lua_State, index: c_int) {
lua_pop(state, 1);
}
pub unsafe fn luaL_loadbuffer(state: *mut lua_State,
buf: *const c_char,
size: usize,
name: *const c_char)
-> c_int {
pub unsafe fn luaL_loadbuffer(
state: *mut lua_State,
buf: *const c_char,
size: usize,
name: *const c_char,
) -> c_int {
luaL_loadbufferx(state, buf, size, name, ptr::null())
}

View File

@ -88,8 +88,10 @@ pub trait FromLuaMulti<'a>: Sized {
fn from_lua_multi(values: LuaMultiValue<'a>, lua: &'a Lua) -> LuaResult<Self>;
}
type LuaCallback = Box<for<'lua> FnMut(&'lua Lua, LuaMultiValue<'lua>)
-> LuaResult<LuaMultiValue<'lua>>>;
type LuaCallback = Box<
for<'lua> FnMut(&'lua Lua, LuaMultiValue<'lua>)
-> LuaResult<LuaMultiValue<'lua>>,
>;
struct LuaRef<'lua> {
lua: &'lua Lua,
@ -261,9 +263,10 @@ impl<'lua> LuaTable<'lua> {
/// Loop over each key, value pair in the table
pub fn for_each_pair<K, V, F>(&self, mut f: F) -> LuaResult<()>
where K: FromLua<'lua>,
V: FromLua<'lua>,
F: FnMut(K, V)
where
K: FromLua<'lua>,
V: FromLua<'lua>,
F: FnMut(K, V),
{
let lua = self.0.lua;
unsafe {
@ -358,8 +361,10 @@ impl<'lua> LuaFunction<'lua> {
for arg in args {
lua.push_value(lua.state, arg)?;
}
handle_error(lua.state,
pcall_with_traceback(lua.state, nargs, ffi::LUA_MULTRET))?;
handle_error(
lua.state,
pcall_with_traceback(lua.state, nargs, ffi::LUA_MULTRET),
)?;
let nresults = ffi::lua_gettop(lua.state) - stack_start;
let mut results = LuaMultiValue::new();
for _ in 0..nresults {
@ -427,9 +432,10 @@ pub struct LuaThread<'lua>(LuaRef<'lua>);
impl<'lua> LuaThread<'lua> {
/// If this thread has yielded a value, will return Some, otherwise the thread is finished and
/// this will return None.
pub fn resume<A: ToLuaMulti<'lua>, R: FromLuaMulti<'lua>>(&self,
args: A)
-> LuaResult<Option<R>> {
pub fn resume<A: ToLuaMulti<'lua>, R: FromLuaMulti<'lua>>(
&self,
args: A,
) -> LuaResult<Option<R>> {
let lua = self.0.lua;
unsafe {
stack_guard(lua.state, 0, || {
@ -447,8 +453,10 @@ impl<'lua> LuaThread<'lua> {
lua.push_value(thread_state, arg)?;
}
handle_error(lua.state,
resume_with_traceback(thread_state, lua.state, nargs))?;
handle_error(
lua.state,
resume_with_traceback(thread_state, lua.state, nargs),
)?;
let nresults = ffi::lua_gettop(thread_state);
let mut results = LuaMultiValue::new();
@ -520,8 +528,10 @@ impl<T: LuaUserDataType> LuaUserDataMethods<T> {
where M: 'static + for<'a, 'lua> FnMut(&'lua Lua, &'a T, LuaMultiValue<'lua>)
-> LuaResult<LuaMultiValue<'lua>>
{
self.methods
.insert(name.to_owned(), Self::box_method(method));
self.methods.insert(
name.to_owned(),
Self::box_method(method),
);
}
/// Add a regular method as a function which accepts a &mut T parameter
@ -529,8 +539,10 @@ impl<T: LuaUserDataType> LuaUserDataMethods<T> {
where M: 'static + for<'a, 'lua> FnMut(&'lua Lua, &'a mut T, LuaMultiValue<'lua>)
-> LuaResult<LuaMultiValue<'lua>>
{
self.methods
.insert(name.to_owned(), Self::box_method_mut(method));
self.methods.insert(
name.to_owned(),
Self::box_method_mut(method),
);
}
/// Add a regular method as a function which accepts generic arguments, the first argument will
@ -572,12 +584,12 @@ impl<T: LuaUserDataType> LuaUserDataMethods<T> {
-> LuaResult<LuaMultiValue<'lua>>
{
Box::new(move |lua, mut args| if let Some(front) = args.pop_front() {
let userdata = LuaUserData::from_lua(front, lua)?;
let userdata = userdata.borrow::<T>()?;
method(lua, &userdata, args)
} else {
Err("No userdata supplied as first argument to method".into())
})
let userdata = LuaUserData::from_lua(front, lua)?;
let userdata = userdata.borrow::<T>()?;
method(lua, &userdata, args)
} else {
Err("No userdata supplied as first argument to method".into())
})
}
@ -586,12 +598,12 @@ impl<T: LuaUserDataType> LuaUserDataMethods<T> {
-> LuaResult<LuaMultiValue<'lua>>
{
Box::new(move |lua, mut args| if let Some(front) = args.pop_front() {
let userdata = LuaUserData::from_lua(front, lua)?;
let mut userdata = userdata.borrow_mut::<T>()?;
method(lua, &mut userdata, args)
} else {
Err("No userdata supplied as first argument to method".into())
})
let userdata = LuaUserData::from_lua(front, lua)?;
let mut userdata = userdata.borrow_mut::<T>()?;
method(lua, &mut userdata, args)
} else {
Err("No userdata supplied as first argument to method".into())
})
}
}
@ -623,8 +635,9 @@ impl<'lua> LuaUserData<'lua> {
}
fn inspect<'a, T, R, F>(&'a self, func: F) -> LuaResult<R>
where T: LuaUserDataType,
F: FnOnce(&'a RefCell<T>) -> LuaResult<R>
where
T: LuaUserDataType,
F: FnOnce(&'a RefCell<T>) -> LuaResult<R>,
{
unsafe {
let lua = self.0.lua;
@ -641,9 +654,11 @@ impl<'lua> LuaUserData<'lua> {
return Err("value has no metatable".into());
}
ffi::lua_rawgeti(lua.state,
ffi::LUA_REGISTRYINDEX,
lua.userdata_metatable::<T>()? as ffi::lua_Integer);
ffi::lua_rawgeti(
lua.state,
ffi::LUA_REGISTRYINDEX,
lua.userdata_metatable::<T>()? as ffi::lua_Integer,
);
if ffi::lua_rawequal(lua.state, -1, -2) == 0 {
return Err("wrong metatable type for lua userdata".into());
}
@ -681,13 +696,15 @@ impl Lua {
ffi::luaL_openlibs(state);
stack_guard(state, 0, || {
ffi::lua_pushlightuserdata(state,
&LUA_USERDATA_REGISTRY_KEY as *const u8 as *mut c_void);
ffi::lua_pushlightuserdata(
state,
&LUA_USERDATA_REGISTRY_KEY as *const u8 as *mut c_void,
);
let registered_userdata =
ffi::lua_newuserdata(state,
mem::size_of::<RefCell<HashMap<TypeId, c_int>>>()) as
*mut RefCell<HashMap<TypeId, c_int>>;
let registered_userdata = ffi::lua_newuserdata(
state,
mem::size_of::<RefCell<HashMap<TypeId, c_int>>>(),
) as *mut RefCell<HashMap<TypeId, c_int>>;
ptr::write(registered_userdata, RefCell::new(HashMap::new()));
ffi::lua_newtable(state);
@ -703,9 +720,10 @@ impl Lua {
}).unwrap();
stack_guard(state, 0, || {
ffi::lua_pushlightuserdata(state,
&FUNCTION_METATABLE_REGISTRY_KEY as *const u8 as
*mut c_void);
ffi::lua_pushlightuserdata(
state,
&FUNCTION_METATABLE_REGISTRY_KEY as *const u8 as *mut c_void,
);
ffi::lua_newtable(state);
@ -744,30 +762,39 @@ impl Lua {
}
}
pub fn load<'lua, R: FromLuaMulti<'lua>>(&'lua self,
source: &str,
name: Option<&str>)
-> LuaResult<R> {
pub fn load<'lua, R: FromLuaMulti<'lua>>(
&'lua self,
source: &str,
name: Option<&str>,
) -> LuaResult<R> {
unsafe {
stack_guard(self.state, 0, || {
let stack_start = ffi::lua_gettop(self.state);
handle_error(self.state,
if let Some(name) = name {
let name = CString::new(name.to_owned())?;
ffi::luaL_loadbuffer(self.state,
source.as_ptr() as *const c_char,
source.len(),
name.as_ptr())
} else {
ffi::luaL_loadbuffer(self.state,
source.as_ptr() as *const c_char,
source.len(),
ptr::null())
})?;
handle_error(
self.state,
if let Some(name) = name {
let name = CString::new(name.to_owned())?;
ffi::luaL_loadbuffer(
self.state,
source.as_ptr() as *const c_char,
source.len(),
name.as_ptr(),
)
} else {
ffi::luaL_loadbuffer(
self.state,
source.as_ptr() as *const c_char,
source.len(),
ptr::null(),
)
},
)?;
check_stack(self.state, 2)?;
handle_error(self.state,
pcall_with_traceback(self.state, 0, ffi::LUA_MULTRET))?;
handle_error(
self.state,
pcall_with_traceback(self.state, 0, ffi::LUA_MULTRET),
)?;
let nresults = ffi::lua_gettop(self.state) - stack_start;
let mut results = LuaMultiValue::new();
@ -789,23 +816,29 @@ impl Lua {
// "return", then as a statement. This is the same thing the
// actual lua repl does.
let return_source = "return ".to_owned() + source;
let mut res = ffi::luaL_loadbuffer(self.state,
return_source.as_ptr() as *const c_char,
return_source.len(),
ptr::null());
let mut res = ffi::luaL_loadbuffer(
self.state,
return_source.as_ptr() as *const c_char,
return_source.len(),
ptr::null(),
);
if res == ffi::LUA_ERRSYNTAX {
ffi::lua_pop(self.state, 1);
res = ffi::luaL_loadbuffer(self.state,
source.as_ptr() as *const c_char,
source.len(),
ptr::null());
res = ffi::luaL_loadbuffer(
self.state,
source.as_ptr() as *const c_char,
source.len(),
ptr::null(),
);
}
handle_error(self.state, res)?;
check_stack(self.state, 2)?;
handle_error(self.state,
pcall_with_traceback(self.state, 0, ffi::LUA_MULTRET))?;
handle_error(
self.state,
pcall_with_traceback(self.state, 0, ffi::LUA_MULTRET),
)?;
let nresults = ffi::lua_gettop(self.state) - stack_start;
let mut results = LuaMultiValue::new();
@ -838,9 +871,10 @@ impl Lua {
}
pub fn create_table<'lua, K, V, I>(&'lua self, cont: I) -> LuaResult<LuaTable>
where K: ToLua<'lua>,
V: ToLua<'lua>,
I: IntoIterator<Item = (K, V)>
where
K: ToLua<'lua>,
V: ToLua<'lua>,
I: IntoIterator<Item = (K, V)>,
{
unsafe {
stack_guard(self.state, 0, || {
@ -858,14 +892,16 @@ impl Lua {
}
pub fn create_array_table<'lua, T, I>(&'lua self, cont: I) -> LuaResult<LuaTable>
where T: ToLua<'lua>,
I: IntoIterator<Item = T>
where
T: ToLua<'lua>,
I: IntoIterator<Item = T>,
{
self.create_table(cont.into_iter().enumerate().map(|(k, v)| (k + 1, v)))
}
pub fn create_function<F>(&self, func: F) -> LuaResult<LuaFunction>
where F: 'static + for<'a> FnMut(&'a Lua, LuaMultiValue<'a>) -> LuaResult<LuaMultiValue<'a>>
where
F: 'static + for<'a> FnMut(&'a Lua, LuaMultiValue<'a>) -> LuaResult<LuaMultiValue<'a>>,
{
self.create_callback_function(Box::new(func))
}
@ -884,21 +920,24 @@ impl Lua {
}
pub fn create_userdata<T>(&self, data: T) -> LuaResult<LuaUserData>
where T: LuaUserDataType
where
T: LuaUserDataType,
{
unsafe {
stack_guard(self.state, 0, move || {
check_stack(self.state, 2)?;
let data = RefCell::new(data);
let data_userdata = ffi::lua_newuserdata(self.state,
mem::size_of::<RefCell<T>>()) as
*mut RefCell<T>;
let data_userdata =
ffi::lua_newuserdata(self.state, mem::size_of::<RefCell<T>>()) as
*mut RefCell<T>;
ptr::write(data_userdata, data);
ffi::lua_rawgeti(self.state,
ffi::LUA_REGISTRYINDEX,
self.userdata_metatable::<T>()? as ffi::lua_Integer);
ffi::lua_rawgeti(
self.state,
ffi::LUA_REGISTRYINDEX,
self.userdata_metatable::<T>()? as ffi::lua_Integer,
);
ffi::lua_setmetatable(self.state, -2);
@ -987,9 +1026,10 @@ impl Lua {
t.to_lua_multi(self)
}
pub fn unpack<'lua, T: FromLuaMulti<'lua>>(&'lua self,
value: LuaMultiValue<'lua>)
-> LuaResult<T> {
pub fn unpack<'lua, T: FromLuaMulti<'lua>>(
&'lua self,
value: LuaMultiValue<'lua>,
) -> LuaResult<T> {
T::from_lua_multi(value, self)
}
@ -1003,7 +1043,7 @@ impl Lua {
};
let func = &mut *(ffi::lua_touserdata(state, ffi::lua_upvalueindex(1)) as
*mut LuaCallback);
*mut LuaCallback);
let nargs = ffi::lua_gettop(state);
let mut args = LuaMultiValue::new();
@ -1026,14 +1066,15 @@ impl Lua {
stack_guard(self.state, 0, move || {
check_stack(self.state, 2)?;
let func_userdata = ffi::lua_newuserdata(self.state,
mem::size_of::<LuaCallback>()) as
*mut LuaCallback;
let func_userdata =
ffi::lua_newuserdata(self.state, mem::size_of::<LuaCallback>()) as
*mut LuaCallback;
ptr::write(func_userdata, func);
ffi::lua_pushlightuserdata(self.state,
&FUNCTION_METATABLE_REGISTRY_KEY as *const u8 as
*mut c_void);
ffi::lua_pushlightuserdata(
self.state,
&FUNCTION_METATABLE_REGISTRY_KEY as *const u8 as *mut c_void,
);
ffi::lua_gettable(self.state, ffi::LUA_REGISTRYINDEX);
ffi::lua_setmetatable(self.state, -2);
@ -1137,13 +1178,17 @@ impl Lua {
}
unsafe fn push_ref(&self, state: *mut ffi::lua_State, lref: &LuaRef) {
assert_eq!(lref.lua.main_state,
self.main_state,
"Lua instance passed LuaValue created from a different Lua");
assert_eq!(
lref.lua.main_state,
self.main_state,
"Lua instance passed LuaValue created from a different Lua"
);
ffi::lua_rawgeti(state,
ffi::LUA_REGISTRYINDEX,
lref.registry_id as ffi::lua_Integer);
ffi::lua_rawgeti(
state,
ffi::LUA_REGISTRYINDEX,
lref.registry_id as ffi::lua_Integer,
);
}
unsafe fn pop_ref(&self, state: *mut ffi::lua_State) -> LuaRef {
@ -1176,11 +1221,13 @@ impl Lua {
stack_guard(self.state, 0, move || {
check_stack(self.state, 3)?;
ffi::lua_pushlightuserdata(self.state,
&LUA_USERDATA_REGISTRY_KEY as *const u8 as *mut c_void);
ffi::lua_pushlightuserdata(
self.state,
&LUA_USERDATA_REGISTRY_KEY as *const u8 as *mut c_void,
);
ffi::lua_gettable(self.state, ffi::LUA_REGISTRYINDEX);
let registered_userdata = ffi::lua_touserdata(self.state, -1) as
*mut RefCell<HashMap<TypeId, c_int>>;
*mut RefCell<HashMap<TypeId, c_int>>;
let mut map = (*registered_userdata).borrow_mut();
ffi::lua_pop(self.state, 1);
@ -1205,8 +1252,10 @@ impl Lua {
check_stack(self.state, methods.methods.len() as c_int * 2)?;
for (k, m) in methods.methods {
push_string(self.state, &k);
self.push_value(self.state,
LuaValue::Function(self.create_callback_function(m)?))?;
self.push_value(
self.state,
LuaValue::Function(self.create_callback_function(m)?),
)?;
ffi::lua_rawset(self.state, -3);
}
@ -1219,8 +1268,10 @@ impl Lua {
push_string(self.state, "__index");
ffi::lua_pushvalue(self.state, -1);
ffi::lua_gettable(self.state, -3);
self.push_value(self.state,
LuaValue::Function(self.create_callback_function(m)?))?;
self.push_value(
self.state,
LuaValue::Function(self.create_callback_function(m)?),
)?;
ffi::lua_pushcclosure(self.state, meta_index_impl, 2);
ffi::lua_rawset(self.state, -3);
} else {
@ -1242,8 +1293,10 @@ impl Lua {
LuaMetaMethod::Call => "__call",
};
push_string(self.state, name);
self.push_value(self.state,
LuaValue::Function(self.create_callback_function(m)?))?;
self.push_value(
self.state,
LuaValue::Function(self.create_callback_function(m)?),
)?;
ffi::lua_rawset(self.state, -3);
}
}

View File

@ -41,12 +41,14 @@ fn test_load() {
None,
).unwrap();
assert!(module.has("func").unwrap());
assert_eq!(module
.get::<_, LuaFunction>("func")
.unwrap()
.call::<_, String>(())
.unwrap(),
"hello");
assert_eq!(
module
.get::<_, LuaFunction>("func")
.unwrap()
.call::<_, String>(())
.unwrap(),
"hello"
);
}
#[test]
@ -92,22 +94,30 @@ fn test_table() {
let table3 = globals.get::<_, LuaTable>("table3").unwrap();
assert_eq!(table1.length().unwrap(), 5);
assert_eq!(table1.pairs::<i64, i64>().unwrap(),
vec![(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)]);
assert_eq!(
table1.pairs::<i64, i64>().unwrap(),
vec![(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)]
);
assert_eq!(table2.length().unwrap(), 0);
assert_eq!(table2.pairs::<i64, i64>().unwrap(), vec![]);
assert_eq!(table2.array_values::<i64>().unwrap(), vec![]);
assert_eq!(table3.length().unwrap(), 5);
assert_eq!(table3.array_values::<Option<i64>>().unwrap(),
vec![Some(1), Some(2), None, Some(4), Some(5)]);
assert_eq!(
table3.array_values::<Option<i64>>().unwrap(),
vec![Some(1), Some(2), None, Some(4), Some(5)]
);
globals
.set("table4",
lua.create_array_table(vec![1, 2, 3, 4, 5]).unwrap())
.set(
"table4",
lua.create_array_table(vec![1, 2, 3, 4, 5]).unwrap(),
)
.unwrap();
let table4 = globals.get::<_, LuaTable>("table4").unwrap();
assert_eq!(table4.pairs::<i64, i64>().unwrap(),
vec![(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)]);
assert_eq!(
table4.pairs::<i64, i64>().unwrap(),
vec![(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)]
);
}
#[test]
@ -124,8 +134,10 @@ fn test_function() {
).unwrap();
let concat = globals.get::<_, LuaFunction>("concat").unwrap();
assert_eq!(concat.call::<_, String>(hlist!["foo", "bar"]).unwrap(),
"foobar");
assert_eq!(
concat.call::<_, String>(hlist!["foo", "bar"]).unwrap(),
"foobar"
);
}
#[test]
@ -149,8 +161,10 @@ fn test_bind() {
concat = concat.bind("foo").unwrap();
concat = concat.bind("bar").unwrap();
concat = concat.bind(hlist!["baz", "baf"]).unwrap();
assert_eq!(concat.call::<_, String>(hlist!["hi", "wut"]).unwrap(),
"foobarbazbafhiwut");
assert_eq!(
concat.call::<_, String>(hlist!["hi", "wut"]).unwrap(),
"foobarbazbafhiwut"
);
}
#[test]
@ -331,8 +345,10 @@ fn test_lua_multi() {
let concat = globals.get::<_, LuaFunction>("concat").unwrap();
let mreturn = globals.get::<_, LuaFunction>("mreturn").unwrap();
assert_eq!(concat.call::<_, String>(hlist!["foo", "bar"]).unwrap(),
"foobar");
assert_eq!(
concat.call::<_, String>(hlist!["foo", "bar"]).unwrap(),
"foobar"
);
let hlist_pat![a, b] = mreturn.call::<_, HList![u64, u64]>(hlist![]).unwrap();
assert_eq!((a, b), (1, 2));
let hlist_pat![a, b, LuaVariadic(v)] = mreturn.call::<_, HList![u64, u64, LuaVariadic<u64>]>(hlist![]).unwrap();
@ -423,9 +439,9 @@ fn test_error() {
None,
).unwrap();
let rust_error_function =
lua.create_function(|_, _| Err(LuaExternalError(Box::new(TestError)).into()))
.unwrap();
let rust_error_function = lua.create_function(
|_, _| Err(LuaExternalError(Box::new(TestError)).into()),
).unwrap();
globals
.set("rust_error_function", rust_error_function)
.unwrap();

View File

@ -30,23 +30,30 @@ pub unsafe fn check_stack(state: *mut ffi::lua_State, amount: c_int) -> LuaResul
// results in an error and the stack is smaller than the value before the call, then this is
// unrecoverable and this will panic.
pub unsafe fn stack_guard<F, R>(state: *mut ffi::lua_State, change: c_int, op: F) -> LuaResult<R>
where F: FnOnce() -> LuaResult<R>
where
F: FnOnce() -> LuaResult<R>,
{
let expected = ffi::lua_gettop(state) + change;
assert!(expected >= 0,
"lua stack error, too many values would be popped");
assert!(
expected >= 0,
"lua stack error, too many values would be popped"
);
let res = op();
let top = ffi::lua_gettop(state);
if res.is_ok() {
assert_eq!(ffi::lua_gettop(state),
expected,
"lua stack error, expected stack to be {}, got {}",
expected,
top);
assert_eq!(
ffi::lua_gettop(state),
expected,
"lua stack error, expected stack to be {}, got {}",
expected,
top
);
} else {
assert!(top >= expected,
"lua stack error, {} too many values popped",
top - expected);
assert!(
top >= expected,
"lua stack error, {} too many values popped",
top - expected
);
if top > expected {
ffi::lua_settop(state, expected);
}
@ -60,15 +67,18 @@ pub unsafe fn stack_guard<F, R>(state: *mut ffi::lua_State, change: c_int, op: F
// still longjmps, and have all the same dangers as longjmps, so extreme care
// must still be taken in code that uses this function. Does not call
// lua_checkstack, and uses 2 extra stack spaces.
pub unsafe fn error_guard<F, R>(state: *mut ffi::lua_State,
nargs: c_int,
nresults: c_int,
func: F)
-> LuaResult<R>
where F: FnOnce(*mut ffi::lua_State) -> LuaResult<R> + UnwindSafe
pub unsafe fn error_guard<F, R>(
state: *mut ffi::lua_State,
nargs: c_int,
nresults: c_int,
func: F,
) -> LuaResult<R>
where
F: FnOnce(*mut ffi::lua_State) -> LuaResult<R> + UnwindSafe,
{
unsafe extern "C" fn call_impl<F>(state: *mut ffi::lua_State) -> c_int
where F: FnOnce(*mut ffi::lua_State) -> c_int
where
F: FnOnce(*mut ffi::lua_State) -> c_int,
{
let func = ffi::lua_touserdata(state, -1) as *mut F;
let func = mem::replace(&mut *func, mem::uninitialized());
@ -76,12 +86,14 @@ pub unsafe fn error_guard<F, R>(state: *mut ffi::lua_State,
func(state)
}
unsafe fn cpcall<F>(state: *mut ffi::lua_State,
nargs: c_int,
nresults: c_int,
mut func: F)
-> LuaResult<()>
where F: FnOnce(*mut ffi::lua_State) -> c_int
unsafe fn cpcall<F>(
state: *mut ffi::lua_State,
nargs: c_int,
nresults: c_int,
mut func: F,
) -> LuaResult<()>
where
F: FnOnce(*mut ffi::lua_State) -> c_int,
{
ffi::lua_pushcfunction(state, call_impl::<F>);
ffi::lua_insert(state, -(nargs + 1));
@ -119,10 +131,10 @@ pub unsafe fn push_string(state: *mut ffi::lua_State, s: &str) {
pub unsafe extern "C" fn destructor<T>(state: *mut ffi::lua_State) -> c_int {
match catch_unwind(|| {
let obj = &mut *(ffi::lua_touserdata(state, 1) as *mut T);
mem::replace(obj, mem::uninitialized());
0
}) {
let obj = &mut *(ffi::lua_touserdata(state, 1) as *mut T);
mem::replace(obj, mem::uninitialized());
0
}) {
Ok(r) => r,
Err(p) => {
push_error(state, WrappedError::Panic(p));
@ -136,7 +148,8 @@ pub unsafe extern "C" fn destructor<T>(state: *mut ffi::lua_State) -> c_int {
// longjmp). The error or panic is wrapped in such a way that when calling pop_error back on
// the rust side, it will resume the panic.
pub unsafe fn callback_error<R, F>(state: *mut ffi::lua_State, f: F) -> R
where F: FnOnce() -> LuaResult<R> + UnwindSafe
where
F: FnOnce() -> LuaResult<R> + UnwindSafe,
{
match catch_unwind(f) {
Ok(Ok(r)) => r,
@ -154,8 +167,10 @@ pub unsafe fn callback_error<R, F>(state: *mut ffi::lua_State, f: F) -> R
// Pops a WrappedError off of the top of the stack, if it is a WrappedError::Error, returns it, if
// it is a WrappedError::Panic, clears the current stack and panics.
pub unsafe fn pop_error(state: *mut ffi::lua_State) -> LuaError {
assert!(ffi::lua_gettop(state) > 0,
"pop_error called with nothing on the stack");
assert!(
ffi::lua_gettop(state) > 0,
"pop_error called with nothing on the stack"
);
// Pop an error off of the lua stack and interpret it as a wrapped error, or as a string. If
// the error cannot be interpreted as a string simply print that it was an unprintable error.
@ -195,10 +210,11 @@ pub unsafe fn pop_error(state: *mut ffi::lua_State) -> LuaError {
// ffi::lua_pcall with a message handler that gives a nice traceback. If the caught error is
// actually a LuaError, will simply pass the error along. Does not call
// checkstack, and uses 2 extra stack spaces.
pub unsafe fn pcall_with_traceback(state: *mut ffi::lua_State,
nargs: c_int,
nresults: c_int)
-> c_int {
pub unsafe fn pcall_with_traceback(
state: *mut ffi::lua_State,
nargs: c_int,
nresults: c_int,
) -> c_int {
unsafe extern "C" fn message_handler(state: *mut ffi::lua_State) -> c_int {
if is_wrapped_error(state, 1) {
if !is_panic_error(state, 1) {
@ -208,7 +224,13 @@ pub unsafe fn pcall_with_traceback(state: *mut ffi::lua_State,
.to_str()
.unwrap()
.to_owned();
push_error(state, WrappedError::Error(LuaError::with_chain(error, LuaErrorKind::CallbackError(traceback))));
push_error(
state,
WrappedError::Error(LuaError::with_chain(
error,
LuaErrorKind::CallbackError(traceback),
)),
);
}
} else {
let s = ffi::lua_tolstring(state, 1, ptr::null_mut());
@ -229,10 +251,11 @@ pub unsafe fn pcall_with_traceback(state: *mut ffi::lua_State,
ret
}
pub unsafe fn resume_with_traceback(state: *mut ffi::lua_State,
from: *mut ffi::lua_State,
nargs: c_int)
-> c_int {
pub unsafe fn resume_with_traceback(
state: *mut ffi::lua_State,
from: *mut ffi::lua_State,
nargs: c_int,
) -> c_int {
let res = ffi::lua_resume(state, from, nargs);
if res != ffi::LUA_OK && res != ffi::LUA_YIELD {
if is_wrapped_error(state, 1) {
@ -243,7 +266,13 @@ pub unsafe fn resume_with_traceback(state: *mut ffi::lua_State,
.to_str()
.unwrap()
.to_owned();
push_error(from, WrappedError::Error(LuaError::with_chain(error, LuaErrorKind::CallbackError(traceback))));
push_error(
from,
WrappedError::Error(LuaError::with_chain(
error,
LuaErrorKind::CallbackError(traceback),
)),
);
}
} else {
let s = ffi::lua_tolstring(state, 1, ptr::null_mut());
@ -314,7 +343,7 @@ unsafe fn push_error(state: *mut ffi::lua_State, err: WrappedError) {
ffi::luaL_checkstack(state, 6, ptr::null());
let err_userdata = ffi::lua_newuserdata(state, mem::size_of::<Option<WrappedError>>()) as
*mut Option<WrappedError>;
*mut Option<WrappedError>;
ptr::write(err_userdata, Some(err));
@ -323,8 +352,10 @@ unsafe fn push_error(state: *mut ffi::lua_State, err: WrappedError) {
ffi::lua_pop(state, 1);
ffi::lua_newtable(state);
ffi::lua_pushlightuserdata(state,
&ERROR_METATABLE_REGISTRY_KEY as *const u8 as *mut c_void);
ffi::lua_pushlightuserdata(
state,
&ERROR_METATABLE_REGISTRY_KEY as *const u8 as *mut c_void,
);
ffi::lua_pushvalue(state, -2);
push_string(state, "__gc");
@ -343,9 +374,11 @@ unsafe fn push_error(state: *mut ffi::lua_State, err: WrappedError) {
// Checks if the error at the given index is a WrappedError::Panic
unsafe fn is_panic_error(state: *mut ffi::lua_State, index: c_int) -> bool {
assert_ne!(ffi::lua_checkstack(state, 2),
0,
"somehow not enough stack space to check if an error is panic");
assert_ne!(
ffi::lua_checkstack(state, 2),
0,
"somehow not enough stack space to check if an error is panic"
);
let index = ffi::lua_absindex(state, index);
@ -380,9 +413,11 @@ unsafe fn is_panic_error(state: *mut ffi::lua_State, index: c_int) -> bool {
}
unsafe fn is_wrapped_error(state: *mut ffi::lua_State, index: c_int) -> bool {
assert_ne!(ffi::lua_checkstack(state, 2),
0,
"somehow not enough stack space to check if an error is rrapped");
assert_ne!(
ffi::lua_checkstack(state, 2),
0,
"somehow not enough stack space to check if an error is rrapped"
);
let index = ffi::lua_absindex(state, index);
@ -402,7 +437,9 @@ unsafe fn is_wrapped_error(state: *mut ffi::lua_State, index: c_int) -> bool {
}
unsafe fn get_error_metatable(state: *mut ffi::lua_State) -> c_int {
ffi::lua_pushlightuserdata(state,
&ERROR_METATABLE_REGISTRY_KEY as *const u8 as *mut c_void);
ffi::lua_pushlightuserdata(
state,
&ERROR_METATABLE_REGISTRY_KEY as *const u8 as *mut c_void,
);
ffi::lua_gettable(state, ffi::LUA_REGISTRYINDEX)
}