use std::os::raw::c_void; use mlua::{Function, LightUserData, Lua, LuaString, Number, Result, Thread}; #[test] fn test_lightuserdata() -> Result<()> { let lua = Lua::new(); let globals = lua.globals(); lua.load( r#" function id(a) return a end "#, ) .exec()?; let res = globals .get::("id")? .call::(LightUserData(42 as *mut c_void))?; assert_eq!(res, LightUserData(42 as *mut c_void)); Ok(()) } #[test] fn test_boolean_type_metatable() -> Result<()> { let lua = Lua::new(); let mt = lua.create_table()?; mt.set("__add", Function::wrap(|a, b| Ok(a || b)))?; assert_eq!(lua.type_metatable::(), None); lua.set_type_metatable::(Some(mt.clone())); assert_eq!(lua.type_metatable::().unwrap(), mt); lua.load(r#"assert(true + true == true)"#).exec().unwrap(); lua.load(r#"assert(true + false == true)"#).exec().unwrap(); lua.load(r#"assert(false + true == true)"#).exec().unwrap(); lua.load(r#"assert(false + false == false)"#).exec().unwrap(); Ok(()) } #[test] fn test_lightuserdata_type_metatable() -> Result<()> { let lua = Lua::new(); let mt = lua.create_table()?; mt.set( "__add", Function::wrap(|a: LightUserData, b: LightUserData| { Ok(LightUserData((a.0 as usize + b.0 as usize) as *mut c_void)) }), )?; lua.set_type_metatable::(Some(mt.clone())); assert_eq!(lua.type_metatable::().unwrap(), mt); let res = lua .load( r#" local a, b = ... return a + b "#, ) .call::(( LightUserData(42 as *mut c_void), LightUserData(100 as *mut c_void), )) .unwrap(); assert_eq!(res, LightUserData(142 as *mut c_void)); Ok(()) } #[test] fn test_number_type_metatable() -> Result<()> { let lua = Lua::new(); let mt = lua.create_table()?; mt.set("__call", Function::wrap(|n1: f64, n2: f64| Ok(n1 * n2)))?; lua.set_type_metatable::(Some(mt.clone())); assert_eq!(lua.type_metatable::().unwrap(), mt); lua.load(r#"assert((1.5)(3.0) == 4.5)"#).exec().unwrap(); lua.load(r#"assert((5)(5) == 25)"#).exec().unwrap(); Ok(()) } #[test] fn test_string_type_metatable() -> Result<()> { let lua = Lua::new(); let mt = lua.create_table()?; mt.set( "__add", Function::wrap(|a: String, b: String| Ok(format!("{a}{b}"))), )?; lua.set_type_metatable::(Some(mt.clone())); assert_eq!(lua.type_metatable::().unwrap(), mt); lua.load(r#"assert(("foo" + "bar") == "foobar")"#).exec().unwrap(); Ok(()) } #[test] fn test_function_type_metatable() -> Result<()> { let lua = Lua::new(); let mt = lua.create_table()?; mt.set( "__index", Function::wrap(|_: Function, key: String| Ok(format!("function.{key}"))), )?; lua.set_type_metatable::(Some(mt.clone())); assert_eq!(lua.type_metatable::(), Some(mt)); lua.load(r#"assert((function() end).foo == "function.foo")"#) .exec() .unwrap(); Ok(()) } #[test] fn test_thread_type_metatable() -> Result<()> { let lua = Lua::new(); let mt = lua.create_table()?; mt.set( "__index", Function::wrap(|_: Thread, key: String| Ok(format!("thread.{key}"))), )?; lua.set_type_metatable::(Some(mt.clone())); assert_eq!(lua.type_metatable::(), Some(mt)); lua.load(r#"assert((coroutine.create(function() end)).foo == "thread.foo")"#) .exec() .unwrap(); Ok(()) }