extern crate hlua; #[test] fn readwrite() { #[derive(Clone)] struct Foo; impl<'lua, L> hlua::Push for Foo where L: hlua::AsMutLua<'lua> { type Err = hlua::Void; fn push_to_lua(self, lua: L) -> Result, (hlua::Void, L)> { Ok(hlua::push_userdata(self, lua, |_| {})) } } impl<'lua, L> hlua::PushOne for Foo where L: hlua::AsMutLua<'lua> {} impl<'lua, L> hlua::LuaRead for Foo where L: hlua::AsMutLua<'lua> { fn lua_read_at_position(lua: L, index: i32) -> Result { let val: Result, _> = hlua::LuaRead::lua_read_at_position(lua, index); val.map(|d| d.clone()) } } let mut lua = hlua::Lua::new(); lua.set("a", Foo); let _: Foo = lua.get("a").unwrap(); } #[test] fn destructor_called() { use std::sync::{Arc, Mutex}; let called = Arc::new(Mutex::new(false)); struct Foo { called: Arc>, } impl Drop for Foo { fn drop(&mut self) { let mut called = self.called.lock().unwrap(); (*called) = true; } } impl<'lua, L> hlua::Push for Foo where L: hlua::AsMutLua<'lua> { type Err = hlua::Void; fn push_to_lua(self, lua: L) -> Result, (hlua::Void, L)> { Ok(hlua::push_userdata(self, lua, |_| {})) } } impl<'lua, L> hlua::PushOne for Foo where L: hlua::AsMutLua<'lua> {} { let mut lua = hlua::Lua::new(); lua.set("a", Foo { called: called.clone() }); } let locked = called.lock().unwrap(); assert!(*locked); } #[test] fn type_check() { #[derive(Clone)] struct Foo; impl<'lua, L> hlua::Push for Foo where L: hlua::AsMutLua<'lua> { type Err = hlua::Void; fn push_to_lua(self, lua: L) -> Result, (hlua::Void, L)> { Ok(hlua::push_userdata(self, lua, |_| {})) } } impl<'lua, L> hlua::PushOne for Foo where L: hlua::AsMutLua<'lua> {} impl<'lua, L> hlua::LuaRead for Foo where L: hlua::AsMutLua<'lua> { fn lua_read_at_position(lua: L, index: i32) -> Result { let val: Result, _> = hlua::LuaRead::lua_read_at_position(lua, index); val.map(|d| d.clone()) } } #[derive(Clone)] struct Bar; impl<'lua, L> hlua::Push for Bar where L: hlua::AsMutLua<'lua> { type Err = hlua::Void; fn push_to_lua(self, lua: L) -> Result, (hlua::Void, L)> { Ok(hlua::push_userdata(self, lua, |_| {})) } } impl<'lua, L> hlua::PushOne for Bar where L: hlua::AsMutLua<'lua> {} impl<'lua, L> hlua::LuaRead for Bar where L: hlua::AsMutLua<'lua> { fn lua_read_at_position(lua: L, index: i32) -> Result { let val: Result, _> = hlua::LuaRead::lua_read_at_position(lua, index); val.map(|d| d.clone()) } } let mut lua = hlua::Lua::new(); lua.set("a", Foo); let x: Option = lua.get("a"); assert!(x.is_none()) } #[test] fn metatables() { #[derive(Clone)] struct Foo; impl<'lua, L> hlua::Push for Foo where L: hlua::AsMutLua<'lua> { type Err = hlua::Void; fn push_to_lua(self, lua: L) -> Result, (hlua::Void, L)> { Ok(hlua::push_userdata(self, lua, |mut table| { table.set("__index".to_string(), vec![("test".to_string(), hlua::function0(|| 5))]); })) } } impl<'lua, L> hlua::PushOne for Foo where L: hlua::AsMutLua<'lua> {} let mut lua = hlua::Lua::new(); lua.set("a", Foo); let x: i32 = lua.execute("return a.test()").unwrap(); assert_eq!(x, 5); } #[test] fn multiple_userdata() { #[derive(Clone)] struct Integer(u32); impl<'lua, L> hlua::Push for Integer where L: hlua::AsMutLua<'lua> { type Err = hlua::Void; fn push_to_lua(self, lua: L) -> Result, (hlua::Void, L)> { Ok(hlua::push_userdata(self, lua, |_| { })) } } impl<'lua, L> hlua::PushOne for Integer where L: hlua::AsMutLua<'lua> {} impl<'lua, L> hlua::LuaRead for Integer where L: hlua::AsMutLua<'lua> { fn lua_read_at_position(lua: L, index: i32) -> Result { let val: Result, _> = hlua::LuaRead::lua_read_at_position(lua, index); val.map(|d| d.clone()) } } #[derive(Debug, Clone, PartialEq, Eq)] struct BigInteger(u32, u32, u32, u32); impl<'lua, L> hlua::Push for BigInteger where L: hlua::AsMutLua<'lua> { type Err = hlua::Void; fn push_to_lua(self, lua: L) -> Result, (hlua::Void, L)> { Ok(hlua::push_userdata(self, lua, |_| { })) } } impl<'lua, L> hlua::PushOne for BigInteger where L: hlua::AsMutLua<'lua> {} impl<'lua, L> hlua::LuaRead for BigInteger where L: hlua::AsMutLua<'lua> { fn lua_read_at_position(lua: L, index: i32) -> Result { let val: Result, _> = hlua::LuaRead::lua_read_at_position(lua, index); val.map(|d| d.clone()) } } let axpy_float = |a: f64, x: Integer, y: Integer| a * x.0 as f64 + y.0 as f64; let axpy_float_2 = |a: f64, x: Integer, y: f64| a * x.0 as f64 + y; let broadcast_mul = |k: Integer, v: BigInteger| BigInteger(k.0 * v.0, k.0 * v.1, k.0 * v.2, k.0 * v.3); let collapse = |a: f32, k: Integer, v: BigInteger| (k.0 * v.0) as f32 * a + (k.0 * v.1) as f32 * a + (k.0 * v.2) as f32 * a + (k.0 * v.3) as f32 * a; let mut lua = hlua::Lua::new(); let big_integer = BigInteger(531,246,1,953); lua.set("a", Integer(19)); lua.set("b", Integer(114)); lua.set("c", Integer(96)); lua.set("d", Integer(313)); lua.set("v", big_integer.clone()); lua.set("add", hlua::function2(|x: Integer, y: Integer| Integer(x.0 + y.0))); lua.set("axpy", hlua::function3(|a: Integer, x: Integer, y: Integer| Integer(a.0 * x.0 + y.0))); lua.set("axpy_float", hlua::function3(&axpy_float)); lua.set("axpy_float_2", hlua::function3(&axpy_float_2)); lua.set("broadcast_mul", hlua::function2(&broadcast_mul)); lua.set("collapse", hlua::function3(&collapse)); assert_eq!(lua.execute::("return add(a, b)").unwrap().0, 19 + 114); assert_eq!(lua.execute::("return add(b, c)").unwrap().0, 114 + 96); assert_eq!(lua.execute::("return add(c, d)").unwrap().0, 96 + 313); assert_eq!(lua.execute::("return axpy(a, b, c)").unwrap().0, 19 * 114 + 96); assert_eq!(lua.execute::("return axpy(b, c, d)").unwrap().0, 114 * 96 + 313); assert_eq!(lua.execute::("return axpy_float(2.5, c, d)").unwrap(), axpy_float(2.5, Integer(96), Integer(313))); assert_eq!(lua.execute::("return broadcast_mul(a, v)").unwrap(), broadcast_mul(Integer(19), big_integer.clone())); assert_eq!(lua.execute::("return broadcast_mul(b, v)").unwrap(), broadcast_mul(Integer(114), big_integer.clone())); assert_eq!(lua.execute::("return collapse(19.25, c, v)").unwrap(), collapse(19.25, Integer(96), big_integer.clone())); }