@@ -18,7 +18,7 @@ use crate::string::String;
1818use crate :: table:: Table ;
1919use crate :: thread:: Thread ;
2020use crate :: types:: {
21- AppDataRef , AppDataRefMut , ArcReentrantMutexGuard , Integer , MaybeSend , Number , ReentrantMutex ,
21+ AppDataRef , AppDataRefMut , ArcReentrantMutexGuard , Integer , LuaType , MaybeSend , Number , ReentrantMutex ,
2222 ReentrantMutexGuard , RegistryKey , VmState , XRc , XWeak ,
2323} ;
2424use crate :: userdata:: { AnyUserData , UserData , UserDataProxy , UserDataRegistry , UserDataStorage } ;
@@ -1337,24 +1337,66 @@ impl Lua {
13371337 unsafe { self . lock ( ) . make_userdata ( UserDataStorage :: new ( ud) ) }
13381338 }
13391339
1340- /// Sets the metatable for a Luau builtin vector type.
1341- #[ cfg( any( feature = "luau" , doc) ) ]
1342- #[ cfg_attr( docsrs, doc( cfg( feature = "luau" ) ) ) ]
1343- pub fn set_vector_metatable ( & self , metatable : Option < Table > ) {
1340+ /// Sets the metatable for a Lua builtin type.
1341+ ///
1342+ /// The metatable will be shared by all values of the given type.
1343+ ///
1344+ /// # Examples
1345+ ///
1346+ /// Change metatable for Lua boolean type:
1347+ ///
1348+ /// ```
1349+ /// # use mlua::{Lua, Result, Function};
1350+ /// # fn main() -> Result<()> {
1351+ /// # let lua = Lua::new();
1352+ /// let mt = lua.create_table()?;
1353+ /// mt.set("__tostring", lua.create_function(|_, b: bool| Ok(if b { 2 } else { 0 }))?)?;
1354+ /// lua.set_type_metatable::<bool>(Some(mt));
1355+ /// lua.load("assert(tostring(true) == '2')").exec()?;
1356+ /// # Ok(())
1357+ /// # }
1358+ /// ```
1359+ #[ allow( private_bounds) ]
1360+ pub fn set_type_metatable < T : LuaType > ( & self , metatable : Option < Table > ) {
13441361 let lua = self . lock ( ) ;
13451362 let state = lua. state ( ) ;
13461363 unsafe {
13471364 let _sg = StackGuard :: new ( state) ;
13481365 assert_stack ( state, 2 ) ;
13491366
1350- #[ cfg( not( feature = "luau-vector4" ) ) ]
1351- ffi:: lua_pushvector ( state, 0. , 0. , 0. ) ;
1352- #[ cfg( feature = "luau-vector4" ) ]
1353- ffi:: lua_pushvector ( state, 0. , 0. , 0. , 0. ) ;
1367+ match T :: TYPE_ID {
1368+ ffi:: LUA_TBOOLEAN => {
1369+ ffi:: lua_pushboolean ( state, 0 ) ;
1370+ }
1371+ ffi:: LUA_TLIGHTUSERDATA => {
1372+ ffi:: lua_pushlightuserdata ( state, ptr:: null_mut ( ) ) ;
1373+ }
1374+ ffi:: LUA_TNUMBER => {
1375+ ffi:: lua_pushnumber ( state, 0. ) ;
1376+ }
1377+ #[ cfg( feature = "luau" ) ]
1378+ ffi:: LUA_TVECTOR => {
1379+ #[ cfg( not( feature = "luau-vector4" ) ) ]
1380+ ffi:: lua_pushvector ( state, 0. , 0. , 0. ) ;
1381+ #[ cfg( feature = "luau-vector4" ) ]
1382+ ffi:: lua_pushvector ( state, 0. , 0. , 0. , 0. ) ;
1383+ }
1384+ ffi:: LUA_TSTRING => {
1385+ ffi:: lua_pushstring ( state, b"\0 " as * const u8 as * const _ ) ;
1386+ }
1387+ ffi:: LUA_TFUNCTION => match self . load ( "function() end" ) . eval :: < Function > ( ) {
1388+ Ok ( func) => lua. push_ref ( & func. 0 ) ,
1389+ Err ( _) => return ,
1390+ } ,
1391+ ffi:: LUA_TTHREAD => {
1392+ ffi:: lua_newthread ( state) ;
1393+ }
1394+ _ => { }
1395+ }
13541396 match metatable {
13551397 Some ( metatable) => lua. push_ref ( & metatable. 0 ) ,
13561398 None => ffi:: lua_pushnil ( state) ,
1357- } ;
1399+ }
13581400 ffi:: lua_setmetatable ( state, -2 ) ;
13591401 }
13601402 }
0 commit comments